释放对象的校验和不正确

Posted

技术标签:

【中文标题】释放对象的校验和不正确【英文标题】:incorrect checksum for freed object 【发布时间】:2015-03-08 20:25:59 【问题描述】:

我收到此错误(内存位置因运行而异):

q2(4910,0x7fff7a1d4300) malloc: *** error for object 0x7fdf79c04bd8: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

这是崩溃的函数:

public:
// construct a 'rows X cols' matrix.
SMatrix(int rows, int cols) 
    if (rows<1 || cols<1) 
        cout<<"Invalid row/col value(s).";
        exit(-1);
    
    this->_rows = rows;
    this->_cols = cols;
    this->_vertical = new simpleNode [rows];
    this->_horizontal = new simpleNode [cols];
    if (this->_vertical == NULL || this->_horizontal==NULL) 
        cout<<"Exiting";
        exit(-1);
    
    initArrays();

它在这一行崩溃:

  this->_horizontal = new simpleNode [cols];

调用的函数:

int main() 
      SMatrix bigM(500,500);
      bigM.setElement(10,20,17);
      cout <<" bigM - total size in bytes: (implementation depended): "
       << bigM.sizeInBytes() << endl << endl; 

      SMatrix m1(7,10),m2(7,10),m4(10,2),m5(7,2); //Crashes on m4(10,2)

其他可能相关的功能:

struct simpleNode 
    Node* _next;
;
int _rows; //Number of rows in this SMatrix
int _cols; //Number of columns in this SMatrix
simpleNode * _vertical; //array (simpleNode)
simpleNode * _horizontal;  //array (simpleNode)
/*Initiate the horizontal/vertical arrays to point to null*/
void initArrays() 
    int i;
    for (i=0; i<this->_rows; i++)
        this->_horizontal[i]._next = NULL;
    for (i=0; i<this->_cols; i++)
        this->_vertical[i]._next = NULL;

我在 OSX 上。我用 -g 编译并用 GDB 运行它,但 程序正常退出。 如果我不使用 XCode,我该如何调试?此外,有关如何解决问题的提示也会非常有帮助。

编辑:我正在运行输出文件,有时它会运行,而另一些则给我错误。似乎是随机顺序。此外,当我在 gdb 上运行该程序时,它永远不会失败,它总是正确退出。为什么会这样?

【问题讨论】:

【参考方案1】:

您的限制在您的初始化代码中被颠倒了。您可以像这样创建数组:

this->_vertical = new simpleNode [rows];   // <== uses rows for sizing vertical
this->_horizontal = new simpleNode [cols]; // <== uses cols for sizing horizontal

但是你的初始化是这样的:

for (i=0; i<this->_rows; i++) // <== limit is rows, but you walking horizontal
    this->_horizontal[i]._next = NULL;
for (i=0; i<this->_cols; i++) // <== limit is cols, but you walking vertical
    this->_vertical[i]._next = NULL;

除非rowscols 是相同的值,否则此代码会调用未定义的行为。通过使用与分配大小相同的值来解决此问题

for (i=0; i<this->_rows; i++)
    this->_vertical[i]._next = NULL;
for (i=0; i<this->_cols; i++)
    this->_horizontal[i]._next = NULL;

老实说,更好的方法是使用 RAII 容器,例如 std::vector&lt;&gt;,但我把它留给你作为练习。

祝你好运,希望对你有所帮助。

【讨论】:

【参考方案2】:

由于您在调试器中,您应该查看内存位置0x7fff7a1d4300 并查看那里有什么。内存中的数据可能有助于找出问题所在。

发生的情况是以下之一:

    你正在释放一个对象两次,

    你正在释放一个从未分配过的指针

    您正在通过一个无效指针进行写入,该指针先前指向一个已被释放的对象

我认为发生的事情是第 3 位。

我的答案基于this 答案。


相关讨论位于here。


相关question关于gdb。

【讨论】:

我不在调试器中。 但是你使用了-g 标志。 @Airwavezx 你能告诉我如何查看内存位置吗? 不同故障的内存位置不同。我应该在 gdb 中查看什么值?此外,当我在 gdb 上运行该程序时,它永远不会失败,它总是正确退出。为什么会这样? 不知道多说。

以上是关于释放对象的校验和不正确的主要内容,如果未能解决你的问题,请参考以下文章

realloc 错误:释放对象的校验和不正确

已释放对象的校验和不正确 - 对象在被释放后可能已被修改。我该如何解决?

CGContextDrawImage(Swift)上的间歇性“释放对象的校验和不正确”错误

Java 套接字:TCP 校验和不正确

在objective-c中释放数组的内存问题

TCP 校验和与wireshark 校验和不匹配(正好相差1)