编写释放指针并将其赋值为NULL的函数

11

最近面试时问到我这个问题,基本上是写一个函数来结合释放和赋值为null的功能。我的回答如下:

void main()
{
      int *ptr;
      ptr = new int;
      ptr = newdelete(ptr);
}

(int*) newdelete (int *ptr)
{
      delete(ptr);
      return NULL;
}
执行后,main 中的局部变量 ptr 将保持空值,因为我从 newdelete 函数中返回了它。如果我只是在 newdelete 函数中赋值为 NULL,那么 newdelete 局部变量的 ptr 将被设置为空值而不是 main 的局部变量 ptr
我认为我的解决方案是正确的,面试官也接受了。然而,他期望得到另一个答案。他坚持说我不能从函数中返回 NULL,但仍然要实现所需的结果。
有没有办法实现这个要求?我能想到的是传递另一个参数,即指向 mainptr 指针的指针,但我不明白为什么这比我做的更好!

1
传递指针的引用。 - Martin York
8
在C++中,它是int main()。始终如此,没有例外。 - sbi
我会非常警惕那些需要将指针置空的商店。为什么他们要使用裸指针?而且在不再需要它们之后,为什么还要保留它们呢? - sbi
在C语言中,这可能是一个相当好的实践,但在C++中并不适用。对于C语言,如果指针是结构体的一部分,则可以保留指针,例如,在跟踪代码时,我们可以轻松地确定哪些指针拥有内存,哪些不拥有。 - stinky472
1
@Goz:更准确地说,https://dev59.com/PnM_5IYBdhLWcg3wslfs#1265866。 - Matthieu M.
显示剩余3条评论
4个回答

36
有没有办法实现这个?
template <typename T> void safeDelete(T*& p){
    delete p;
    p = 0;
}

int main(int argc, char** arv){
    int * i = new int;
    safeDelete(i);
    return 0;
}

4
由于只有代码,这种方法更好的原因是您可以确保在调用期间指针将被设置为 null。对于问题中的代码,您可能会忘记返回值:“/*p = */newdelete(p)”,此时内存将被释放但指针仍为非空。 - David Rodríguez - dribeas
6
请记住,你需要为数组创建第二个版本。 - Björn Pollex
2
当然问题是:这有什么安全的?你是在隐藏漏洞而不是检查它们... - Matthieu M.
1
@SigTerm:它相当于try { } catch (...) { },因为你有可能忽略一个错误(因为你确实检查了NULL,是吧?)。此外,它也没有解决别名问题:将一个指针置空并不会将该指针的所有副本都置空。简而言之,最坏的情况下,它会隐藏错误,在最好的情况下也是无用的。我个人更喜欢使用RAII来进行真正的所有权管理方案。在评论中,我已经链接了一个重复的答案。 - Matthieu M.
1
@SigTerm:我同意结束讨论,我们显然有非常不同的意见 :) - Matthieu M.
显示剩余5条评论

8
我猜他期望的是类似于以下内容:

我猜他期望的是类似于以下内容:

void reset(int*& ptr)
{
      delete(ptr);
      ptr = NULL;
}

更干净的解决方案是使用 boost::shared_ptr<> 并简单地调用 ptr.reset()。不过,我猜这可能不是一个选择。


1
如果他们不想要共享指针语义,怎么办?如果您不需要它,那么没有必要增加额外的开销。 - Peter Alexander
1
@Peter,在这种情况下可以使用scoped_ptr,它同样提供了reset功能。 - stinky472
@Peter:我应该提到scoped_ptr而不是shared_ptr(我更经常使用后者,所以它首先出现在我的脑海中)。无论是共享的还是作用域的,使用智能指针比任何与原始指针结合使用的safeDelete()函数更安全。 - ereOn
1
尽管我会使用模板示例,但我赞同这一个,因为它符合他们在面试中想要看到的内容。即使模板示例非常简单,但可能会浪费更多宝贵的面试时间。 - Merlyn Morgan-Graham

1
如果不是要编写一个函数,你也可以编写一个宏来完成这个任务:
#define my_delete(x) { delete x; x = NULL; }

当然,这样调用会让你陷入各种麻烦:

my_delete(ptr++)

所以,我认为我更喜欢非宏方式。


1

你不需要

你可以使用像auto_ptrshared_ptr这样会自动置空的智能指针。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接