由于我的C ++不是很好,这可能是一个非常简单/明显的答案,但它肯定让我难过。请记住它有点晚了,我有点累了。我在这里得到了这段代码:
void TestFunc(int *pVar)
{
cout << endl << *pVar << endl;
delete pVar;
pVar = nullptr;
}
int main(int argc, char *argv[])
{
int *z(new int);
*z = 5;
TestFunc(z);
if (z == nullptr)
cout << "z Successfully Deleted!" << endl;
else cout << "z NOT deleted!" << endl;
return 0;
}
程序编译得很好,没有错误或警告。当我运行它时,它会显示5
,就像我期望的那样。但是,它说z NOT deleted!
。我很好奇为什么pVar
没有被设置为nullptr
,即使我明确地在我的TestFunc()函数中设置它。任何帮助,将不胜感激。如果重要,那么这就是Visual Studio 2010,而只是一个常规的非托管C ++应用程序。
答案 0 :(得分:5)
因为通过值传递(即作为副本)。
如果您希望传递变量本身(而不仅仅是其复制的值),请使用
void TestFunc(int *&pVar)
代替。
请注意,delete
仅关注指针,而不关心指针。因此,“删除”指针的副本会删除与原始指针相同的内容,因为在任何一种情况下,您都要删除它们的目标,这些目标是相同的。
答案 1 :(得分:2)
TestFunc
按值接受指针,因此在函数内部将其设置为null实际上只会影响函数中的副本,并且对调用者不可见。因此pVar
设置为空,但z
中的main()
不是因为它们是不同的变量。
要使调用者看到更改,请通过引用或双指针传递指针。
答案 2 :(得分:1)
已经很晚了(抱歉!!!)。
z
按值传递。 z
不是pVar
。您已将nullptr
的值分配给pVar
,而不是z
。
答案 3 :(得分:0)
您提出的“成语”通常被称为安全删除。
它已经在C中已知(虽然当时它是free
):将刚刚释放/删除的指针清零以避免这样做两次。
麻烦的是,你将当前的指针归零,但它的任何副本仍然指向相同的内存区域,现在它包含垃圾。
内存处理是一个难题,基本概念是所有权。在任何时候,都应该很好地识别特定内存区域的所有者,他们应该负责在适当的时候将其返回给系统。
这方面的第一步是使用智能指针,例如std::unique_ptr
或boost::scoped_ptr
。对于共享所有权(仅限专家),std::shared_ptr
可能会派上用场,但您还没有。
如果您在代码中写了delete
,则表示您正在暴露自己。它本身并不坏,但它需要仔细审查,并使代码变得脆弱(即,可能会在更改时中断)。在你的情况下:
int main() {
boost::scoped_ptr<int> i(new 5);
foo(*i);
} // memory returned to system by ~scoped_ptr()