gpt4 book ai didi

c++ - 删除这些指针时出错

转载 作者:行者123 更新时间:2023-11-30 03:28:32 25 4
gpt4 key购买 nike

我知道当我用 new 初始化一个指针时,我需要删除指针,否则会发生内存泄漏。我有一个这样设置的类:

class foobar
{
private:

//! Pointer to the global nodal list
int *p_test1;

//! Pointer to the global block label list
int *p_test2;

public:
foobar(int *test1, int *test2)
{
p_test1 = test1;
p_test2 = test2;
}

~foobar()
{
delete p_test1;
delete p_test2;
}
};

现在,当调用析构函数时,程序崩溃并且控制台显示程序退出并返回代码 -6。

调试窗口指出:

程序接收信号SIGABRT

当我完成调用堆栈时,最后一项是析构函数。堆栈似乎试图释放内存但失败了。

我想知道为什么会这样?使用类设置释放内存的首选方法是什么。

作为旁注,如果我在析构函数中注释掉代码,当 foobar 类的实例完成时,指针当然不会被释放。但是,当我调用该类的另一个实例时(假设实例的创建是由用户按下 GUI 上的按钮决定的),程序就会崩溃。再说一遍,这是为什么呢?我有一种感觉,这与没有正确销毁指针有关。

最佳答案

正如评论中提到的,这个例子中没有new,所以很难解释newdelete之间的平衡。

规则是如果你新建一个指针,你应该删除它。

int * p = new int( 5 );

std::cout << "The value of p is " << *p << std::endl;

delete p;

但是,如果你使用了一个对象,因为你没有新建它,你不应该(通常)删除它。

void somefunction( int * p )
{
std::cout << "The value of p is " << *p << std::endl;

delete p; // this looks smelly - deleting a pointer which was allocated.
}

为了尝试简化这个问题(我应该删除哪些指针),现代 C++ 有一些很好的指南。

资源获取即初始化

RAII 将资源放入类中。完整的类(与指针相反)具有非常清晰的生命周期。当它因为超出范围而被销毁时,将调用析构函数。

 class PointerHolder {
int * mp;
public:
PointerHolder( int value ) : mp( NULL) {
mp = new int( value );
}
~PointerHolder() {
delete mp;
}
}

虽然上面的例子打破了5的规则。

5(或零)法则

上面 PointerHolder 的问题是它没有实现所有 5 个特殊运算符。

PointerHolder a( 12 );
PointerHolder b( 10 );

a = b; // What is going to happen?????

a获取b的指针的值,销毁秒时,是对同一 block 内存的第二次delete,程序崩溃。

5 条规则,如果您实现了析构函数移动运算符复制构造函数运算符= 你应该实现(或删除所有这些)。

在这种情况下,删除移动和复制运算符将生成一个简单的 unique_ptr

零规则是,如果一个类实现了所有运算符,或者一个都没有实现,则该类的可重用性更高。

如果您只需要实现部分运算符,您可能没有确定“资源”——它应该是一个包含所有 5 个重载运算符的类。

现代 C++

自 C++11 起,new 和 delete 的使用被认为仅限于库编写者。由于使用 std::shared_ptrstd::unique_ptr 为您管理 new delete 生命周期,所以您可以专注于手头的问题。

关于c++ - 删除这些指针时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46518537/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com