我想知道是否有任何标准库函数或其他技巧,我可以通过该技巧查询应用程序是否分配了指针。其实我想做以下事情....
Suupose我有一个函数:
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));
但第三种方法的问题在于 - 内存的重新分配现在是被调用方法的责任,在这里我卡住了,因为我不确定对象是否由应用程序分配。
我在这里发布了这个问题,甚至没有用谷歌搜索它,因为我对它很好奇,如果我得到一个干净的解决方案,对我来说是一个很好的奖励......很抱歉。
如果无法确定对象是否在堆上,那么大师会如何建议我实现我想要的?
答案 0 :(得分:11)
没有可移植的方法来确定指针是否引用具有动态分配的对象,编号
它“为我节省了一些打字”是一个非常糟糕的理由选择一个问题的解决方案而不是另一个。在您提出的三个选项中,第一个显然是最好的,因为它依赖于自动生命周期管理。
也就是说,如果你真的要创建一个对象只是为了传递给DoSomeThing
函数,那么最好的选择可能是DoSomeThing
取SomeObject
的值(或者是const) -参考);那么你根本不需要处理指针。
答案 1 :(得分:3)
我怎么知道是否使用new或者在堆上分配了一个对象 malloc()由当前模块?
你做不到。只给出一个指针值,没有可移植/可靠的方法来确定它是由new
分配,malloc()
,还是它甚至指向免费商店的东西(正如你的第一个方法所示) ,传递的指针实际上可能指向自动存储上的对象)。它甚至可能指向数组中的元素。 DoSomeThing()
无法分辨。
处理此问题的方法是让您的函数用户自己管理内存。第一种方法是通常用于此类的方法,因为堆栈分配是自动的。例如,许多Windows API(大部分是C API)都是这样完成的,类似于第一种方法:
WNDCLASSEX wndcls;
// Fill wndcls structure
::RegisterClassEx(&wndcls);
这里RegisterClassEx()
并不关心我的WNDCLASSEX
是在堆栈上,在免费商店上,还是作为数组的一部分,只要我传入一个实际指向a的指针WNDCLASSEX
。所以你的第一种方法确实是在现实世界中处理它的首选方法。
如果不需要C支持,您还可以使用引用:
void DoSomeThing(SomeObject& out) {}
这种方法的一个优点是用户无法传递NULL
指针,因此您无需检查它。如果DoSomeThing()
没有修改SomeObject
,那么更好的方法是使用const
引用:
void DoSomeThing(const SomeObject& out) {}
这个签名的好处在于它允许这种调用工作:
DoSomeThing(SomeObject(Arg1,Arg2));
因此,您可以在不担心内存管理的情况下获得“减少打字”。
答案 2 :(得分:-1)
首先让我说你几乎肯定会设计一些不好的东西来应对这种情况。
也就是说,你可以通过一些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)