释放对象的校验和不正确

时间:2015-01-10 17:06:53

标签: c++ memory-leaks

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

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上运行它总是正确退出。为什么会这样?

2 个答案:

答案 0 :(得分:5)

您的初始化代码中的限制相反。您可以像这样创建数组:

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;

老实说,一个更好的方法是使用std::vector<>这样的RAII容器,但我把它作为练习留给你。

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

答案 1 :(得分:0)

由于您在调试器中,您应该查看内存位置0x7fff7a1d4300并查看其中的内容。内存中的数据可能有助于弄清楚出了什么问题。

正在发生的事情之一是:

  1. 你正在释放一个物品两次,

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

  3. 您正在编写一个无效指针,该指针先前指向已释放的对象

  4. 我认为会发生什么是No.3。

    我的回答基于this回答。


    相关的讨论在于here


    关于gdb的相关question