释放内存失败:free():下一个大小无效(快):

时间:2012-11-27 00:48:29

标签: c++ debugging memory free allocation

我有一个动态重新分配大小的矩阵类。具体而言:动态重新分配行数组。

但是在某些情况下,当调用矩阵的析构函数时会出现内存释放问题:

  

*** glibc检测到*** ./solver:free():下一个大小无效(快):0x0000000000c112b0 ***

并且该过程正在中止。

Matrix类:

#ifndef __matrix_hpp
#define __matrix_hpp

#include <cstring>
#include <stdexcept>
#include "row.hpp"

using namespace std;

class Matrix {

public:
    Matrix();
    ~Matrix();
    size_t size();
    void resize(size_t size);
    double get(size_t x, size_t y) throw (out_of_range);
    void set(size_t x, size_t y, double value) throw (out_of_range);
    double getfv(size_t y) throw (out_of_range);
    void setfv(size_t y, double value) throw (out_of_range);
    void optimize(size_t y) throw (out_of_range);
    void _print();

private:
    size_t sz;
    Row **data;

};

#endif

重要功能的主体:

Matrix::~Matrix() {
    if (data != NULL) {
        for (size_t i = 0; i < sz; ++i)
            delete data[i];
        delete [] data;
    }
}

void Matrix::resize(size_t size) {
    if (size == sz)
        return;
    Row **newData = new Row *[size];
    if (data != NULL)
        memcpy(newData, data, sz * sizeof(Row*));
    if (size > sz) {
        for (size_t i = sz; i < size; ++i)
            newData[i] = new Row();
    }
    else {
        for (size_t i = size; i < sz; ++i)
            delete data[i];
    }
    delete [] data;
    data = newData;
    sz = size;
}

那就是代码。当我制作一个矩阵然后减小它的大小并调用析构函数时,就会出现问题。例如:

Matrix *matrix = new Matrix();
matrix->resize(10);
matrix->resize(7);
delete matrix;

但是制作更大的矩阵效果还不错:

Matrix *matrix = new Matrix();
matrix->resize(10);
matrix->resize(13);
delete matrix;

最有趣的是,这个例子有效:

Matrix *matrix = new Matrix();
matrix->resize(3);
matrix->resize(2);
delete matrix;

所以我不知道会出现什么问题。有什么建议吗?

3 个答案:

答案 0 :(得分:2)

错误是你在分配的空间之外写的: 罪魁祸首就是这条线

Row **newData = new Row *[size];
if (data != NULL)
    memcpy(newData, data, sz * sizeof(Row*));

如果sz大于大小,那么你会写得太多而且可能会破坏你的堆。将其更改为下面的代码,一切都应该更好。这样,您将始终复制有效数据,并且不会超过您分配的数据。

Row **newData = new Row *[size];
if (data != NULL)
    memcpy(newData, data, (size>sz?sz:size) * sizeof(Row*));

调整从3到2的工作是运气(以及堆如何工作)。

此外,您不检查新的Row []是否失败,但这会导致NULL指针异常。

答案 1 :(得分:1)

经过粗略的考试后,我打赌你的问题是:

if (data != NULL)
    memcpy(newData, data, sz * sizeof(Row*));

如果你从10缩小到7,那么你只需要在一个大小为7的缓冲区上复制10个指针。

答案 2 :(得分:0)

当您分配一些内存并写入该内存的末尾,覆盖您不拥有的用于管理空闲堆的内存时,就会发生这种情况。

查看您写入已分配内存的每个位置。确保您没有写过所请求的内存的末尾并且正确拥有。