我正在与一个大项目合作。由于我们的代码基础设施,基本上所有功能必须通过引用返回":
void doSomething(TYPE &result) {
// do something to result
}
但是,在尝试使用对指针的引用时,我遇到了一些分段错误。特别是当我试图清理记忆时,会发生不好的事情。为了尝试理解段错误,我制作了一个非常简单的测试代码。我的第一次尝试编译并运行没有任何错误:
int main() {
int* a;
delete a; // Seems to cause no problem!
}
由于这有效,我决定尝试使用类似指针的方法:
int main() {
int* a;
delete a; // Suddenly, this line is an "invalid delete".
int*& b = a;
}
为什么突然出现这种错误?此外,如果采取正确的方式"存在是通过引用来清理指针保留的内存,它是什么?
一些研究指出:
我试着在StackOverflow上找到一些答案。根据{{3}}删除NULL指针应该是安全的...我的指针完全没有初始化,所以我可能会做一些愚蠢的事情。但是,在我的大型协作代码中,我必须深入挖掘这种指向NULL的指针。
我还试图了解一般指针的引用。另一篇StackOverflow帖子建议Is it safe to delete a NULL pointer?。这是一个很好的阅读,但没有解决我的问题。
提前致谢!
答案 0 :(得分:2)
对未初始化的指针调用delete会产生未定义的行为。因此,它有时可能不会引起问题,但有时会崩溃。
对未初始化的变量执行的任何类型的访问(除了初始化之外)都会导致未定义的行为。例如阅读,比较,删除它。
答案 1 :(得分:1)
如果你认为未初始化的指针是NULL
,那你就错了。它实际上是未初始化的,访问它的值会导致未定义的行为。
语句delete a
访问a
的值,该值本身会导致未定义的行为。
对任何非相应运算符new生成的非NULL指针使用operator delete会给出未定义的行为(该指针是否具有有效值)。
未定义的行为可以给出任何结果。包括像你描述的不一致。
答案 2 :(得分:0)
您的示例并不是很好,因为“a”在调试模式下只会为NULL,并且在发布模式下将是未定义的。它可以包含任何随机值。
您可能想要在堆栈上创建对象,如下所示:
void foo() {
TYPE myObj; // this calls the default c-tor, creating the obj on stack
// the object will de destroyed when the executions goes out of scope.
// if you pass the object reference to another function that keeps the
// reference for future use you are in trouble, as the object will be
// destroyed when out of this scope...
}
或者,使用new:
在堆上创建对象void foo() {
TYPE * myObj = new TYPE(); // here you need to take care of
// destroying the object yourself (delete myObj)
}
最好是使用智能指针。检查Boost,强烈推荐。 http://www.boost.org/