Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.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++ - Fatal编程技术网

C++ &引用;正在尝试释放无效指针“;在析构函数中检测到错误

C++ &引用;正在尝试释放无效指针“;在析构函数中检测到错误,c++,C++,我正处于编写相当大的代码的开始阶段。我定义了这样一个类: class GPUMD { private: double xhi, xlo, yhi, ylo, zhi, zlo; int numAtoms; Atom *atoms; public: GPUMD(); ~GPUMD(); }; 析构函数定义如下: GPUMD::~GPUMD() { if(atoms != NULL)

我正处于编写相当大的代码的开始阶段。我定义了这样一个类:

class GPUMD {
    private:
        double xhi, xlo, yhi, ylo, zhi, zlo;
        int numAtoms;
        Atom *atoms;
    public:
        GPUMD();
        ~GPUMD();
};
析构函数定义如下:

GPUMD::~GPUMD() {
    if(atoms != NULL)
        delete [] atoms;
}
现在,代码执行以下操作:

int main(int argc, char *argv[]) {
    GPUMD gpumd;
    exit(0);
}
我收到一个glibc检测到的错误:试图释放无效指针。使用valgrind,我看到这个错误跟踪到我的GPUMD析构函数。由于某种原因,原子!=空测试返回true,即使我没有为该指针分配任何内容。为什么呢

编辑:构造函数定义为:

GPUMD::GPUMD() {}

因为
atoms
未被显式初始化为
NULL
或构造函数中的有效指针。将构造函数更改为:

GPUMD::GPUMD() : numAtoms(0), atoms(NULL) {}
请注意,
atoms!=由于
delete[]
指针上的
delete[]
delete
,在
NULL
之前的NULL
检查是多余的。以下是安全的:

GPUMD::~GPUMD() {
    delete [] atoms;
}
由于
GPUMD
中有一个动态分配的成员,您需要防止复制
GPUMD
的实例,或者实现赋值运算符和复制构造函数(请参阅)


作为C++,考虑使用<代码>向量 >(或“代码>向量\代码>”的智能指针),而不是为您管理动态内存。

< P>如果您不给指针分配任何东西(换句话说,如果不初始化它),则其值未定义。它不是
NULL
(好吧,它可能是
NULL
,完全是偶然的,但这种偶然性很小,几乎没有。)只有
静态
变量会自动初始化为零

长话短说,在构造函数中将其初始化为
NULL

GPUMD::GPUMD()
: atoms(NULL)
{ }
或者,如果您不喜欢POD类型的初始值设定项(为什么不?),那么:


请同时显示构造函数。请注意,在删除之前可以省略与
NULL
的比较,因为删除NULL指针是有效的。无保护的
delete[]
通常不是一个好主意,因为指针可能会在其他地方被删除。在这种情况下,如果不明确确保再次将其设置为NULL,这将导致双
delete[]
@NikosChantziaras,仅仅因为指针不是
NULL
并不保证它指向有效对象,正如这个问题很好地显示的那样。保护删除确实提供了100%的保证,而且
NULL
delete
之后插入指针也不会,因为另一个指针可以指向同一个对象。@hmjd-保护删除确实提供了100%的保证--我想你的意思是“不保证”@NikosChantziaras-除了一个例外,绝对没有理由保护
删除
。一个例外是,如果您重载了
操作符delete
,使其模拟了在第一个C标准之前糟糕的旧时代
free
的行为。当时,释放空指针确实造成了各种破坏。这是21世纪。现在需要
free
delete
(sans-override)来允许空指针作为输入,并且在被告知释放/删除空指针时完全不做任何事情。
GPUMD::GPUMD()
{ atoms = NULL; }