I have a class OpenGLRenderer which has a class member mMemoryAllocator that is a std::shared_ptr<MemoryAllocator>. The reason I keep the memory allocator in a shared_ptr, is because even if the shared_ptr<Texture> returned below outlives it's creator theOpenGLRenderer, the MemoryAllocator instance will still be valid if I capture it by value, as it increments the ref count:
std::shared_ptr<Texture> OpenGLRenderer::CreateTexture(TextureType textureType, const std::vector<uint8_t>& textureData, uint32_t textureWidth, uint32_t textureHeight, TextureFormat textureFormat)
{
return std::shared_ptr<Texture>(mMemoryAllocator->AllocateObject<Texture>(
textureData, textureWidth, textureHeight,
textureFormat, textureType, mLogger),
[=](Texture* texture) {
mMemoryAllocator
->DeallocateObject<Texture>(texture);
});
}
...But, it dosn't work. If OpenGLRenderer goes out of scope before the std::shared_ptr<Texture>, the std::shared_ptr<MemoryAllocator> becomes corrupted, and thus the lambda expression goes bonkers. What have I done wrong?
The problem in this case is that lambdas don't capture members of the object, but the this pointer. A simple workaround is to create a local variable and bind that:
std::shared_ptr<Texture>
OpenGLRenderer::CreateTexture(TextureType textureType,
const std::vector<uint8_t>& textureData,
uint32_t textureWidth, uint32_t textureHeight,
TextureFormat textureFormat)
{
std::shared_ptr<AllocatorType> allocator = mMemoryAllocator;
return std::shared_ptr<Texture>(mMemoryAllocator->AllocateObject<Texture>(
textureData, textureWidth, textureHeight,
textureFormat, textureType, mLogger),
[=](Texture* texture) {
allocator
->DeallocateObject<Texture>(texture);
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With