在释放c ++中的内存时释放两次空闲或损坏(输出)

时间:2019-03-05 02:00:22

标签: c++ memory memory-management

我有一个函数,可以在c ++中按如下方式返回2D数组

float** Input_data(float** train_data, int Nv, int N){
float** x_train=new float*[Nv];

int a = 0,b = 0;
for(a = 1;a<= Nv;a++){

    x_train[a] = new float[N+1];

    for(b = 1; b <= N+1; b++){
        if(b == 1){

            x_train[a][b] = 1;

        }else{

        x_train[a][b] = train_data[a][b-1];

        }
    }return x_train;}

上述代码的目的是在第一列中添加一个,并将剩余的数据从train_data指针添加到x_train中。处理并使用x_train后,我尝试按以下方式取消分配x_train

void destroyx_array(float**x_train,int Nv){

for (int free_x = 1;free_x <= Nv;free_x++){
delete[] x_train[free_x];}delete[] x_train;}

并按如下所示调用destroy函数

destroyx_array(x_train,Nv)

Input_data函数工作正常,但是当我尝试destroy_x_array时,它会给我双重释放或损坏(输出)中止(核心转储),有人可以解释我在做什么错吗?谢谢

1 个答案:

答案 0 :(得分:1)

简单地说,您的代码破坏了内存。最好的办法是不使用原始指针,而使用诸如std::vector之类的容器类。

话虽如此,为了修复您当前的代码,问题在于您在这里超出了内存的限制:

for(a = 1;a<= Nv;a++)

a == Nv时,您正在写超出分配的“行”。这看起来像是尝试伪造基于1的数组的一种表现。 C ++中的数组从0开始,而不是1。尝试伪造基于1的数组总是会导致错误和内存损坏。

解决方法是将函数重写为从0而不是1开始,并确保循环迭代到n-1,其中n是总行数:

for (a = 0; a < Nv; ++a)


  

以上代码的目的是在第一栏中添加一个   将来自train_data指针的剩余数据添加到x_train

除了编写用于测试第一列的循环外,您还可以通过使用memcpy来简化此操作:

 for (int i = 0; i < Nv; ++i)
 {
     x_train[i][0] = 1;
     memcpy(&x_train[i][1], &train_data[i][0], N * sizeof(float));
 }  

因此整个功能将如下所示:

float** Input_data(float** train_data, int Nv, int N)
{
    float** x_train=new float*[Nv];
    for(int a = 0; a < Nv; a++)
       x_train[a] = new float[N+1];
    for (int a = 0; a < Nv; a++)
    {
       x_train[i][0] = 1;
       memcpy(&x_train[i][1], &train_data[i][0], N * sizeof(float));
    } 
    return x_train;
}