【问题标题】:Memory error trying to free pointers in struct - C尝试释放结构中的指针的内存错误-C
【发布时间】:2017-01-15 08:55:18
【问题描述】:

代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct Nodo{
    int valor;
    struct Nodo* hijo1;
    struct Nodo* hijo2;
}Nodo;

typedef Nodo* Arreglo;

Arreglo INIC_ARR(int longitud);
void IMP_ARR(Arreglo A,int longitud);
void INIC_ARBOL(Arreglo A, int longitud);
void FREE_ARBOL(Arreglo A, int longitud);


int main(){
    Arreglo A;
    int longitud = 10;
    A = INIC_ARR(10);
    INIC_ARBOL(A,longitud);
    IMP_ARR(A,longitud);
    FREE_ARBOL(A,longitud);
    return 0;
}

Arreglo INIC_ARR(int longitud){
    int i;
    Arreglo A = (Arreglo)calloc(longitud,sizeof(Nodo));
    for(i = 0; i < longitud; i++){
        A[i].valor = rand()%10;
    }
    return A;
}

void IMP_ARR(Arreglo A,int longitud){
    int i;
    for(i = 0;i < longitud; i++){
        printf("[%d,",A[i].valor);
        if(A[i].hijo1 == NULL){
            printf("-,");
        }
        else{
            printf("%d,",(*(A[i].hijo1)).valor);
        }
        if(A[i].hijo2 == NULL){
            printf("-]");
        }
        else{
            printf("%d]",(*(A[i].hijo2)).valor);
        }

    }
    printf("\n");
}

void INIC_ARBOL(Arreglo A, int longitud){
    int i;
    for(i = 0; i < longitud; i++){
        if(2*i + 1 < longitud)
            A[i].hijo1 = &A[2*i + 1];
        if(2*i + 2 < longitud)
            A[i].hijo2 = &A[2*i + 2];
    }
}


void FREE_ARBOL(Arreglo A, int longitud){
    int i;
    for(i = 0; i < longitud; i++){
        free(A[i].hijo1);
        free(A[i].hijo2);
    }
    free(A);
}

我创建了一个结构体(Nodo);每个都有两个在 INIC_ARBOL 函数中初始化的指针。我尝试打印然后使用 FREE_ARBOL 释放它们,然后显示:

[3,6,7][6,5,3][7,5,6][5,2,9][3,1,-][5,-,-][6,-,-][2,-,-][9,-,-][1,-,-]
*** Error in `./a.out': free(): invalid pointer: 0x0000000000a31028 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7f3f8adea725]
/lib/x86_64-linux-gnu/libc.so.6(+0x7ff4a)[0x7f3f8adf2f4a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f3f8adf6abc]
./a.out[0x40096b]
./a.out[0x400696]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f3f8ad93830]
./a.out[0x400579]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:0a 140095                             /home/luis/Documentos/Programacion/C/a.out
00600000-00601000 r--p 00000000 08:0a 140095                             /home/luis/Documentos/Programacion/C/a.out
00601000-00602000 rw-p 00001000 08:0a 140095                             /home/luis/Documentos/Programacion/C/a.out
00a31000-00a52000 rw-p 00000000 00:00 0                                  [heap]
7f3f84000000-7f3f84021000 rw-p 00000000 00:00 0 
7f3f84021000-7f3f88000000 ---p 00000000 00:00 0 
7f3f8ab5d000-7f3f8ab73000 r-xp 00000000 08:09 135547                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3f8ab73000-7f3f8ad72000 ---p 00016000 08:09 135547                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3f8ad72000-7f3f8ad73000 rw-p 00015000 08:09 135547                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3f8ad73000-7f3f8af33000 r-xp 00000000 08:09 141748                     /lib/x86_64-linux-gnu/libc-2.23.so
7f3f8af33000-7f3f8b132000 ---p 001c0000 08:09 141748                     /lib/x86_64-linux-gnu/libc-2.23.so
7f3f8b132000-7f3f8b136000 r--p 001bf000 08:09 141748                     /lib/x86_64-linux-gnu/libc-2.23.so
7f3f8b136000-7f3f8b138000 rw-p 001c3000 08:09 141748                     /lib/x86_64-linux-gnu/libc-2.23.so
7f3f8b138000-7f3f8b13c000 rw-p 00000000 00:00 0 
7f3f8b13c000-7f3f8b162000 r-xp 00000000 08:09 141744                     /lib/x86_64-linux-gnu/ld-2.23.so
7f3f8b340000-7f3f8b343000 rw-p 00000000 00:00 0 
7f3f8b35e000-7f3f8b361000 rw-p 00000000 00:00 0 
7f3f8b361000-7f3f8b362000 r--p 00025000 08:09 141744                     /lib/x86_64-linux-gnu/ld-2.23.so
7f3f8b362000-7f3f8b363000 rw-p 00026000 08:09 141744                     /lib/x86_64-linux-gnu/ld-2.23.so
7f3f8b363000-7f3f8b364000 rw-p 00000000 00:00 0 
7fffddc61000-7fffddc82000 rw-p 00000000 00:00 0                          [stack]
7fffddd39000-7fffddd3b000 r--p 00000000 00:00 0                          [vvar]
7fffddd3b000-7fffddd3d000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Abortado (`

核心'将军)

我对 valgrind 等工具的了解为零,所以如果您能慢慢解释如何解决问题,我将不胜感激。

【问题讨论】:

  • OT:UPPER中的函数名通常用于类函数宏,而不是普通函数。

标签: c struct free dynamic-memory-allocation


【解决方案1】:

小故事:你只有一个calloc,所以你应该只有一个free

此外,由于您在INIC_ARBOL 中有那些ifs(例如if (2*i + 1 &lt; longitud)),因此数组中的半个节点甚至不指向任何东西。我会完全删除typedef Nodo *Arreglo,只在其余代码中使用Node*,这样可以更轻松地阅读代码。

【讨论】:

    【解决方案2】:

    不要传递既不是从内存管理函数返回的也不是空指针的东西,否则你会调用未定义的行为

    删除有问题的部分

    for(i = 0; i < longitud; i++){
        free(A[i].hijo1);
        free(A[i].hijo2);
    }
    

    来自函数FREE_ARBOL()

    【讨论】:

      【解决方案3】:

      在这个函数中

      Arreglo INIC_ARR(int longitud){
          int i;
          Arreglo A = (Arreglo)calloc(longitud,sizeof(Nodo));
          for(i = 0; i < longitud; i++){
              A[i].valor = rand()%10;
          }
          return A;
      }
      

      使用语句分配了一个内存区

      Arreglo A = (Arreglo)calloc(longitud,sizeof(Nodo));
      

      你不能释放动态分配数组的元素

      void FREE_ARBOL(Arreglo A, int longitud){
          int i;
          for(i = 0; i < longitud; i++){
              free(A[i].hijo1);
              free(A[i].hijo2);
          }
          free(A);
      }
      

      因为它们是范围的一部分,并且它们本身并不是动态分配的。

      【讨论】:

      • 所以为了“释放”这两个指针,将: A[i].hijo1 = NULL; A[i].hijo2 = NULL;够了吗?
      • @Luis_V 您可以将它们设置为 NULL。还要考虑到,例如函数 INIC_ARBOL 仅为不到一半的节点设置此数据字段。
      猜你喜欢
      • 1970-01-01
      • 2017-04-07
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      相关资源
      最近更新 更多