在C++中使用delete命令会导致分段错误的原因是什么?

Zac*_*ach 9 c++ segmentation-fault delete-operator

我编写了一个程序来分配类T的新对象,如下所示:

T* obj = new T(tid);  
Run Code Online (Sandbox Code Playgroud)

其中tid是一个int

在我的代码中的其他地方,我正在尝试释放我已分配的对象,它位于向量内,使用:

delete(myVec[i]);  
Run Code Online (Sandbox Code Playgroud)

然后:

myVec[i] = NULL;
Run Code Online (Sandbox Code Playgroud)

有时它会通过而没有任何错误,并且在某些情况下会导致崩溃 - 分段错误.

我在调用delete之前已经检查过,那个对象就在那里 - 我以前没有删除它.

什么可能导致这次崩溃?
这是我将类型T的对象插入向量的代码:

_myVec is global

int add() {     

int tid =  _myVec.size();  
T* newT = new T (tid);  
    if (newT == NULL){  
        return ERR_CODE;  
    }  
    _myVec.push_back(newT);  
//  _myVec.push_back(new T (tid));  

    return tid;  
} 
Run Code Online (Sandbox Code Playgroud)

事实上 - 程序有时会崩溃.
当我用注释行替换push_back行,并保持原样 - 它工作.

但当我用以下代码替换此代码时:

int add() { 

int tid =  _myVec.size();  
    if (newT == NULL){  
        return ERR_CODE;  
    }  
    _myVec.push_back(new T (tid));  

    return tid;  
}  
Run Code Online (Sandbox Code Playgroud)

它在不同的阶段崩溃了......

第二个选项中的newT未使用,仍然 - 改变整个过程......这里发生了什么?

Kla*_*aim 17

Segfaulting意味着尝试操作应用程序无法访问的内存位置.

这意味着您的问题可能来自三种情况:

  1. 尝试使用指向NULL的指针执行某些操作;
  2. 尝试使用未初始化的指针执行某些操作;
  3. 尝试使用指向现在已删除对象的指针执行某些操作;

1)很容易检查所以我假设你已经这样做,因为你取消了向量中的指针.如果您不进行检查,请在删除调用之前执行此操作.这将指出您尝试两次删除对象的情况.3)如果向向量中的指针设置NULL,则不会发生.

2)也可能发生.在你的情况下,你正在使用std :: vector,对吧?确保向量的隐式操作(如内部缓冲区重新分配时不再足够大)不会破坏您的列表.

所以,首先检查你是否删除了NULL指针(注意delete(NULL)不会抛出!这是标准和有效的行为!) - 在你的情况下你不应该试图删除(NULL).然后,如果它永远不会发生,请检查您是否没有使用指针指向垃圾桶的向量填充.例如,你应该确保你熟悉[删除 - 删除成语] [1].


既然你添加了一些代码我认为我可以看到问题:

int tid =  _myVec.size(); 
Run Code Online (Sandbox Code Playgroud)

你使用indice作为id.

现在,一切都取决于您删除对象的方式.(请出示更完整的答案)

  1. 您只需将指针设置为NULL.
  2. 您从向量中删除指针.

如果你只做1),那么它应该是安全的(如果你不打扰有一个增长的矢量并且永远不会被释放而且不会重复使用id).
如果你做2.那么这是完全错误的:每次从向量中移除一个对象时,所有对象仍然包含在被移除的对象位置将被降低一个之后.使任何存储的id /索引无效.

确保你在这一点上保持连贯,这肯定是错误的根源.