shared_ptr没有在线程中发布自定义malloc
shared_ptr not releasing custom malloc in a thread
在我的代码中,我在lambda中创建了一个shared_ptr
,以便将PNG文件保存为后台任务。不幸的是,尽管我有一个shared_ptr
的自定义deleter,但字节似乎没有正确释放。
我用来创建shared_ptr
:的代码
std::shared_ptr<GLubyte> buffer = std::shared_ptr<GLubyte>((GLubyte*) malloc(*dataLength), [](GLubyte* buffer) {
free(buffer);
});
为了保存文件并最终解除分配:
std::thread t([=, buffer = std::move(buffer)]() mutable {
bool done = writePNGFileFromBuffer(path, buffer.get(), width, height);
return done;
});
t.detach();
我曾尝试将buffer.reset()
放入lambda中,但尽管缓冲区为空,但内存并没有被释放。我还试图将创建者功能更改为类似于:
std::shared_ptr<GLubyte> buffer = std::shared_ptr<GLubyte>((GLubyte*) malloc(*dataLength), std::free);
但它也不起作用。现在我一直在使用lambda deleter,因为这样我就可以尝试在里面放一个断点,并检查是否调用了free
,但内存仍然没有释放。
此外,我已经验证了如果我把free(buffer.get())
放在lambda中,这个版本是有效的,但说起来对我来说毫无意义,因为我使用shared_ptr
是为了避免类似的事情。
你能帮我释放这个缓冲区吗?非常感谢。
我编写了这个小测试工具来证明新的/删除操作是正确执行的。
请注意在缓冲区构造函数中使用了new/delete[]。您使用malloc/free会给代码带来臭味。使用free(ptr.get(((隐藏了一些您尚未解决的其他逻辑问题。如果你把这个留在程序中,它稍后会咬你的。
proxy
是一个GLubyte的替代品,它计算分配和销毁的数量,所以我可以用assert
确认每个构造都有相应的销毁。
#include <iostream>
#include <memory>
#include <thread>
#include <cassert>
#include <atomic>
using namespace std;
#define USE_PROXY 1
struct proxy
{
proxy() {
++_count;
}
~proxy() {
--_count;
}
static std::atomic<size_t> _count;
};
std::atomic<size_t> proxy::_count = { 0 };
#if USE_PROXY
using GLubyte = proxy;
#else
//using GLubyte = uint8_t;
#endif
bool writePNGFileFromBuffer(const char* path, const GLubyte* bytes, int width, int height)
{
return true;
}
auto main() -> int
{
{
int dataLength = 10000;
auto buffer = std::shared_ptr<GLubyte>(new GLubyte[dataLength],
[](GLubyte* p) { delete[] p; });
const char* path = "/tmp/foo";
int width = 100, height = 100;
std::thread t([=, buffer = std::move(buffer)]() mutable {
bool done = writePNGFileFromBuffer(path, buffer.get(), width, height);
return done;
});
t.join();
assert(!buffer);
}
assert(proxy::_count == 0);
return 0;
}
为了进一步思考,您可能想知道如何处理write....
函数中的故障案例。目前,返回值正在被丢弃。有几种方法可以解决这个问题——一种是提供一个lambda,当写操作完成时可以调用它。另一种方法是将写操作封装到std::async中。
bool writeSharedPNGFileFromBuffer(const char* path, shared_ptr<const GLubyte> bytes, int width, int height)
{
return writePNGFileFromBuffer(path, bytes.get(), width, height);
}
auto main() -> int
{
{
int dataLength = 100;
auto buffer = std::shared_ptr<GLubyte>(new GLubyte[10000], [](GLubyte* p) { delete[] p; });
const char* path = "/tmp/foo";
int width = 100, height = 100;
auto f = std::async(launch::async, writeSharedPNGFileFromBuffer, path, move(buffer), width, height);
// f is a std::future - a handle to somewhere the result will eventually land.
// perform main thread work here...
// ... and get the return value when we're ready to deal with it
auto written = f.get();
cout << "written: " << written << endl;
assert(!buffer);
}
assert(proxy::_count == 0);
return 0;
}
相关文章:
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- C++自定义比较函数
- 如何比较自定义类的std::变体
- std::设置自定义比较器
- 如何正确实现和访问运算符的各种自定义枚举器
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- 自定义先决条件对移动分配运算符有效吗
- 使用VS Code和CMake Tools运行自定义命令
- 如何创建从Maya(或类似程序)到虚幻引擎的自定义数据导出插件
- std::ranges::elements_view,用于自定义类似元组的数据
- 跟随整数索引列表的自定义类迭代器
- 参数化自定义CMake工具链
- 使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题
- 如何将自定义的malloc添加到Linux中
- C++中 malloc 的自定义实现
- 自定义malloc实现
- 实现自定义malloc(),可以在c++中跟踪分配位置
- shared_ptr没有在线程中发布自定义malloc
- 如何使用munmap自定义malloc