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

C++ 释放内存失败:free():下一个大小无效(fast):,c++,debugging,memory,free,allocation,C++,Debugging,Memory,Free,Allocation,我有一个矩阵类,可以动态地重新分配大小。具体来说:动态地重新分配一个行数组 但在某些情况下,当调用矩阵的析构函数时,会出现内存释放问题: ***glibc检测到***./解算器:free():无效的下一个大小(fast):0x0000000000c112b0*** 这个过程正在中止 矩阵类: #ifndef __matrix_hpp #define __matrix_hpp #include <cstring> #include <stdexcept> #include

我有一个矩阵类,可以动态地重新分配大小。具体来说:动态地重新分配一个行数组

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

***glibc检测到***./解算器:free():无效的下一个大小(fast):0x0000000000c112b0***

这个过程正在中止

矩阵类:

#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 = new Matrix();
matrix->resize(10);
matrix->resize(13);
delete matrix;
最有趣的是,这个例子很有效:

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

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

经过一次非常粗略的检查,我敢打赌问题在于:

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

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

经过非常粗略的检查,我敢打赌问题在于:

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

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

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


检查您写入分配内存的每个位置。确保您的写入不会超过您请求的和合法拥有的内存的末尾。

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


检查您写入分配内存的每个位置。确保您的写入不会超过您请求的和合法拥有的内存的末尾。

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

Row **newData = new Row *[size];
if (data != NULL)
    memcpy(newData, data, sz * sizeof(Row*));
如果sz大于size,那么您将写入太多内容,并可能破坏堆。把它改成下面的代码,一切都会更好。这样,您将始终复制有效数据,并且复制的数据不会超过分配的数据

Row **newData = new Row *[size];
if (data != NULL)
    memcpy(newData, data, (size>sz?sz:size) * sizeof(Row*));
将大小从3调整到2取决于运气(以及堆的工作方式)


此外,您不会检查新行[]是否失败,但这将导致空指针异常

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

Row **newData = new Row *[size];
if (data != NULL)
    memcpy(newData, data, sz * sizeof(Row*));
如果sz大于size,那么您将写入太多内容,并可能破坏堆。把它改成下面的代码,一切都会更好。这样,您将始终复制有效数据,并且复制的数据不会超过分配的数据

Row **newData = new Row *[size];
if (data != NULL)
    memcpy(newData, data, (size>sz?sz:size) * sizeof(Row*));
将大小从3调整到2取决于运气(以及堆的工作方式)


此外,您不会检查新行[]是否失败,但这将导致空指针异常

真管用!非常感谢你。我没注意到。但是为什么自由会有问题呢?我看不出有什么联系。您是否建议检查new是否总是失败数据当您分配内存时,堆将在内存周围存储一些信息,如果您在指定区域之外写入,则会覆盖堆释放缓冲区所需的信息。对于另一个问题,只需检查它是否为newData[i]==NULL,如果为NULL,则返回一个错误(并释放所有分配的内存)。这样就行了!非常感谢你。我没注意到。但是为什么自由会有问题呢?我看不出有什么联系。您是否建议检查new是否总是失败数据当您分配内存时,堆将在内存周围存储一些信息,如果您在指定区域之外写入,则会覆盖堆释放缓冲区所需的信息。对于另一个问题,只需检查它是否为newData[i]==NULL,如果为NULL,则返回一个错误(并释放所有分配的内存)。