我注意到 g++ 足够智能,可以识别函数何时返回指向临时/局部变量的指针,例如
int *foobar()
{
int a;
return &a;
}
将导致:
warning: address of local variable ‘a’ returned
有没有一种方法可以定义函数原型以仅接受编译器可以判断不是临时的指针。 假设我有一个函数
barfoo(int *a_int);
如果有人将指向本地/临时对象的指针传递给 g++,我有没有办法告诉 g++ 抱怨? 这将禁止人们使用无效指针调用 barfoo,并可能节省调试一些烦人的问题。
示例:
void barfoo(int *a)
{
cerr << a << endl;
};
void foobar()
{
int a;
barfoo(&a);
}
我希望编译器抱怨“barfoo(&a)”。
您可以指示编译器将该警告标记为错误。但要小心不要错误地定义你的问题。接受指向局部变量的指针的函数是有效的用例:
int a;
...
do_something (&a);
printf ("%d\n", a);
我认为没有任何方法可以让编译器强制执行它,但您可以通过使用 malloc_size 更早地检测到一些实例。
void someFunc(int * mustBeHeap) {
assert(0!=malloc_size(mustBeHeap));
//do stuff
}
不幸的是,您将从这样的代码中得到误报:
void someOtherFunc() {
int * myInts=(int *)malloc(sizeof(int)*20);
someFunc(&(myInts[3]));
}
它对于分配了 new、boost::pool 等的任何东西都不能很好地工作。事实上,你几乎会从所有东西中得到误报。
此外,malloc_size 是非标准的。
编辑:
在查看了上面关于获取所有权的评论之一后,看起来我所描述的一些误报实际上是您也想检测的情况,因为您打算从指针中释放内存。
不,在那里做你想避免的事情是完全有用的。当函数的原始调用者已经离开调用堆栈时,GCC/G++ 无法猜测采用引用/指针的函数会将其存储在某个位置以供以后重用。
您也许可以设置一个编译器来将警告视为错误(无论如何您都应该这样做!),但我不相信除此之外还有其他方法可以完成您所要求的操作。
在 C++ 中,您可以编写一个“保证堆指针”模板类,其中包含单个实际指针,但具有严格限制的构造函数,因此创建一个的唯一方法是通过
new
。重载足够的运算符,您可以让它的行为几乎像裸指针一样,只是它不会进行转换
来自这样的指针。
(不过,我怀疑这是否值得这么麻烦)。
如果没有充分的理由,永远不要在 C++ 中使用原始指针。在这种情况下,由于您计划获得指针的所有权,因此接受反映该指针的对象。如果您想要独资,请选择
auto_ptr
\ unique_ptr
,否则请选择 shared_ptr
。如果您不拥有所有权,请接受(可能是常量)引用。