我如何知道一个对象是否在堆上分配使用new
How do I know if an object is allocated on the heap using new?
我想知道是否有任何标准库函数或其他技巧,通过它我可以查询指针是否由应用程序分配。实际上我想做下面的事情....
假设我有一个函数:
void DoSomeThing(SomeObject* pObj);
要调用这个函数,我们通常有如下两种选择:
//The first method using stack
SomeObject ObjLocal(Arg1,Arg2);
DoSomething(&ObjLocal);
//The second method using heap
SomeObject* ObjUserAllocated=new SomeObj(Arg1,Arg2);
DoSomeThing(ObjUserAllocated);
//But I like to use code like below (saves me some typing)
DoSomeThing(new SomeObject(Arg1,Arg2));
但是第三种方法的问题是-内存的释放现在是被调用方法的责任,这里我卡住了,因为我不确定对象是否由应用程序分配。
我把这个问题贴在这里,甚至没有谷歌它,因为我很好奇,如果我得到一个干净的解决方案,这将是一个伟大的奖励我…很抱歉。
如果不可能确定一个对象是否在堆上,那么你的大师会建议我如何实现我想要的?
没有可移植的方法来确定指针是否指向动态分配的对象,没有
选择一种解决方案而不是另一种解决方案是一个非常糟糕的理由。在您提供的三个选项中,第一个显然是最好的,因为它依赖于自动生命周期管理。
也就是说,如果你真的要创建一个对象只是为了传递给DoSomeThing
函数,最好的选择可能是让DoSomeThing
通过值(或通过常量引用)获取SomeObject
;那么你就完全不需要处理指针了
我如何知道一个对象是否在堆上使用new或Malloc()由当前模块?
你不能。给定一个指针值,没有可移植/可靠的方法来确定它是由new
分配的,还是由malloc()
分配的,或者它是否指向自由存储上的某个对象(正如您的第一个方法所示,传递的指针实际上可能指向自动存储上的对象)。它甚至可以指向数组中的一个元素。DoSomeThing()
根本看不出来。
处理这个问题的方法是让函数的用户自己管理内存。第一种方法通常用于类似的情况,因为堆栈分配是自动的。例如,很多Windows API(大部分是C API)是这样做的,类似于你的第一个方法:
WNDCLASSEX wndcls;
// Fill wndcls structure
::RegisterClassEx(&wndcls);
这里RegisterClassEx()
不关心我的WNDCLASSEX
是在堆栈上,在自由存储上,还是作为数组的一部分,只要我传递一个指针,实际上指向WNDCLASSEX
。所以你的第一种方法确实是在现实世界中处理它的首选方法。
如果不需要C语言支持,也可以使用引用:
void DoSomeThing(SomeObject& out) {}
这种方法的一个优点是用户不能传递一个NULL
指针,所以你不必检查它。如果DoSomeThing()
没有修改SomeObject
,那么更好的方法是使用const
引用:
void DoSomeThing(const SomeObject& out) {}
这个签名的好处是它允许这种调用工作:
DoSomeThing(SomeObject(Arg1,Arg2));
所以你得到了你想要的"少打字",而不用担心内存管理。
首先让我说,你几乎肯定设计得很糟糕,才会出现这种情况。
也就是说,你可以用一些shared_ptr
滥用来做到这一点:
void DoSomeThing(std::shared_ptr<SomeObject> pObj);
SomeObject obj(arg1, arg2);
DoSomeThing(new SomeObject(arg1, arg2));
DoSomeThing(std::shared_ptr<SomeObject>(&obj, [](SomeObject*){})); // Empty deleter written as C++11 lambda (could write out the functor elsewhere if not using C++11)
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 在C++中,如果我可以直接将整数分配给指针而不使用"new",为什么要使用"new"?
- constexpr new 如何分配内存?
- 这行代码中的内存是如何分配"int **v = new int*[n]; "的?
- 正确分配放置 new 的数组
- 如何分配适合容纳 T 类型对象的缓冲区(可能过度对齐、可能有运算符 new 等)
- 使用new时如何重新分配dyyanmic数组,不使用realloc删除C++?
- 如何在不使用 "new" 关键字的情况下解除分配创建的对象的内存?
- 哪些资源是由智能指针管理的,而它们的内存不是由new分配的
- 使用 'new[]' 运算符分配内存
- (C++)如何在不导致 mem 泄漏的情况下将指针传递到分配了'new'的函数?
- 使用 new in C++(在 Windows 上)分配大于 2GB 的单个对象
- 如何使用 "new" 而不是 malloc 分配内存?
- 当我们在指向未分配 new 运算符的对象的指针上使用 delete 时会发生什么
- C++内存分配 new[] 和删除 []
- 是否可以"delete"分配"new[1]"的内存,反之亦然?
- 是未使用在堆栈或堆上分配"new"分配的对象
- linux上c++内存分配new (nothrow)失败时该怎么做
- 为什么虚拟功能在分配"new"时不能取消实现?
- c++ 分配 *new Object() 来引用