Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 删除这些指针时出错_C++_Pointers - Fatal编程技术网

C++ 删除这些指针时出错

C++ 删除这些指针时出错,c++,pointers,C++,Pointers,我知道当我用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) {

我知道当我用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
delete
之间的平衡

规则是,如果新建指针,则应将其删除

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.
}
尽管上面的例子打破了5的规则

第五条规则(或零) 上面的PointerHolder的问题是,它没有实现所有5个特殊运算符

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

a = b;  // What is going to happen?????
a获取b指针的值,当第二个指针被销毁时,它是对同一块内存的第二次删除,程序崩溃

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

在这种情况下,删除移动和复制操作符将生成一个简单的
唯一\u ptr

零的规则是,如果一个类实现了所有的操作符,或者没有实现任何操作符,那么该类更易于重用

如果您只需要实现一些操作符,那么很可能您还没有识别“资源”——它应该是一个包含所有5个重载操作符的单一类

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

a = b;  // What is going to happen?????
现代C++
由于C++11,new和delete的使用被认为仅限于库编写者。由于使用了
std::shared\u ptr
std::unique\u ptr
为您管理
新的
删除
生命周期,因此您可以专注于手头的问题。

您真的分配了memeory吗?您在代码中的何处使用了新运算符?在析构函数中使用指针的
delete
,表示对象的所有权。现在我们看到您正在向对象传递一个指针并存储它,是谁分配的?相关的
new
在哪里?在代码中,我调用一个函数,返回指向对象的指针。对象本身不是指针。该对象属于另一个类。当此对象发生析构函数时,我不想删除该对象。我只想将这些指针重置回“零”或删除它们。不要用散文来描述您的代码。这是一个相当奇怪的C++代码设计,远远没有什么现代C++ 11后的源码应该看看。考虑不要使用<代码>新建/删除< />代码,如果你不能避免它(通常你应该能够很好地拥有良好的总体架构),那么我宁愿保持<代码>新+删除>代码>在同一个源中的对应对,彼此靠近。此时,你有
new
谁知道在哪里,这里有
delete
,这将使阅读和审查此类源代码变得困难,必须使用大量的推理来查看每个
new
是否与
delete
正确配对(显然,当你遇到崩溃时,它已经不是了)。