当对象包含指针成员时,堆栈上的对象销毁出现分段错误
Segfault on object destruction on the stack when object containing pointer member?
以下场景似乎非常令人困惑(这不是一个工作代码,只是一个非常简化的版本来说明该场景,你明白了):
class A {
private:
B* mb;
public:
A(B *b):mb(b) {}
~A() {
if(NULL != mb) { delete mb; }
}
}
int main(int argc, char **argv) {
B* b = new B();
A* a = new A(b);
delete A; //Everything is fine here
B b;
A* a = new A(&b);
//This will segfault, because b is allocated on the stack?
delete A;
B b;
//This segfaults as well because when it goes out of scope
//the program tries to delete b twice?
A a(&b);
}
如果我正确理解这一点,这是否意味着当它们的类定义看起来像这样时,你再也不能在堆栈上分配像A和B这样的对象了?或者,我只是不为a定义析构函数,然后a和B都可以在堆栈上分配——但这可能很糟糕,可能会导致内存泄漏?(如果有一天其他人查看了代码并决定使用新的A)。
我认为C++相对于Java的主要优势是可以避免新的对象,并始终处理堆栈上的对象以加快速度,但像这样在堆栈或堆上使用对象的灵活性又如何呢?
C++有什么用?那么,以下两种方式中的哪一种应该走呢?
如上定义类A,并始终新建A和B,而以后请记住仅删除A。
定义不带析构函数的类A,然后总是在堆栈上创建A和B,并按值传递对象(但在某些情况下,我不想要公共复制构造函数)。
您假设这个segfault是正确的,因为您正在删除在堆栈上分配的项。您只能删除已用new分配的项目。此外,在同一层代码中分配和释放内存也是一种很好的做法。如果您必须在代码中使用对象B,最好创建B:的副本
class A {
private B* mb;
public:
A(B *b) {
mb = new B(*b); // calls B's copy constructor
}
~A() {
if(NULL != mb) { delete mb; }
}
}
那么应该采用以下两种方式中的哪一种?
两者都没有。使用选项3:根本不要这样做。你说得对,C++的一个优点是你不需要new
和delete
,但你写了一大堆使用new
和delete
的代码。
你想用这个A
解决什么问题?毫无疑问,有比A
更好的方法来解决这个问题。
相关文章:
- 从对象C++中的文件读取内容时出现分段错误
- 尝试将对象插入空指针数组时出现分段错误
- 分段错误(内核转储) C++面向对象编程
- 在C++中,当指向删除和指向不同对象时,分段故障指针
- 当我尝试绘制 sf::Text 对象时,SFML 中的分段错误
- 尝试从另一个类对象获取值时出现分段错误
- 添加两个具有运算符重载的数组对象,从而导致分段错误
- 实例化对象时如何修复分段故障错误
- 多对象手写单链表中的分段错误
- 列表<对象*>迭代器中的分段错误
- 尝试从方法返回指向对象的指针时出现分段错误
- 对ifstream对象调用close时出现分段错误
- 多个对象的插入时出现分段错误
- 创建对象 c++ 时出现分段错误
- 为什么在通过引用传递对象时不断出现分段错误
- wxWidgets UI应用程序在C++中使用4个或多个wxBoxSizer对象时出现分段错误
- 当对象包含指针成员时,堆栈上的对象销毁出现分段错误
- 尝试将调用对象与另一个对象进行比较时出现分段错误
- 使用索引缓冲区对象时出现奇怪的分段错误
- 分段错误(核心转储) - 通过对象访问结构的成员时