c ++对指针的引用:不一致的段错误
c++ reference to pointer: inconsistent segfault
我正在与一个大项目合作。由于我们代码的基础结构,基本上所有函数都必须 "return by reference":
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;
}
为什么会突然出现段错误?另外,如果存在"proper way"通过引用清理指针保留的内存,它是什么?
一些研究笔记:
我试图在 Whosebug 上找到一些答案。根据 Is it safe to delete a NULL pointer? 删除 NULL 指针应该是安全的......我的指针完全未初始化,所以我可能在做一些愚蠢的事情。但是,在我的大型协作代码中,我必须深入挖掘才能将这种指针初始化为 NULL。
我还尝试了解一般的指针引用。另一个 Whosebug post 建议 http://markgodwin.blogspot.co.il/2009/08/c-reference-to-pointer.html。那是一本好书,但没有解决我的问题。
提前致谢!
对未初始化的指针调用 delete 会产生未定义的行为。因此,它有时可能不会给您带来问题,但其他时候可能会崩溃。
对未初始化变量执行的任何类型的访问(除了初始化它)都会导致未定义的行为。例如阅读它,比较它,删除它。
如果您认为未初始化的指针将是 NULL
,那您就错了。它实际上是未初始化的,访问它的值会导致未定义的行为。
语句 delete a
访问 a
的值,这本身会导致未定义的行为。
对不是由相应的 operator new 生成的任何非 NULL 指针使用 operator delete 会产生未定义的行为(无论该指针是否具有有效值)。
未定义的行为可以给出任何结果。包括你描述的不一致。
你的例子不是很好,因为 "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)
}
最好是使用智能指针。检查升压,强烈推荐。
http://www.boost.org/
我正在与一个大项目合作。由于我们代码的基础结构,基本上所有函数都必须 "return by reference":
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;
}
为什么会突然出现段错误?另外,如果存在"proper way"通过引用清理指针保留的内存,它是什么?
一些研究笔记:
我试图在 Whosebug 上找到一些答案。根据 Is it safe to delete a NULL pointer? 删除 NULL 指针应该是安全的......我的指针完全未初始化,所以我可能在做一些愚蠢的事情。但是,在我的大型协作代码中,我必须深入挖掘才能将这种指针初始化为 NULL。
我还尝试了解一般的指针引用。另一个 Whosebug post 建议 http://markgodwin.blogspot.co.il/2009/08/c-reference-to-pointer.html。那是一本好书,但没有解决我的问题。
提前致谢!
对未初始化的指针调用 delete 会产生未定义的行为。因此,它有时可能不会给您带来问题,但其他时候可能会崩溃。
对未初始化变量执行的任何类型的访问(除了初始化它)都会导致未定义的行为。例如阅读它,比较它,删除它。
如果您认为未初始化的指针将是 NULL
,那您就错了。它实际上是未初始化的,访问它的值会导致未定义的行为。
语句 delete a
访问 a
的值,这本身会导致未定义的行为。
对不是由相应的 operator new 生成的任何非 NULL 指针使用 operator delete 会产生未定义的行为(无论该指针是否具有有效值)。
未定义的行为可以给出任何结果。包括你描述的不一致。
你的例子不是很好,因为 "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)
}
最好是使用智能指针。检查升压,强烈推荐。 http://www.boost.org/