2016-09-07 17 views
3

コード:メモリエラー - C

#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)のarraryを作成しました。それぞれにINIC_ARBOL関数で初期化される2つのポインタがあります。私は印刷し、その後、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 (` 

コア」generado)

あなたが何をすべきかを、ゆっくりと私に説明できるので、もし私がvalgrindのようなツール上のゼロ知識を持っています私はそれを感謝する修正する。この機能で

+0

あなたは知識がありません、大丈夫、恥ずかしい、なぜドンじゃない?ハイ・タイムだと思う。 –

+0

OT:UPPERの関数名は、通常、関数のようなマクロで使用され、通常の関数では使用されません。 –

答えて

1

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 FREE_ARBOL(Arreglo A, int longitud){ 
    int i; 
    for(i = 0; i < longitud; i++){ 
     free(A[i].hijo1); 
     free(A[i].hijo2); 
    } 
    free(A); 
} 

の自由な要素をしないことがあり声明

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

を使用してメモリの一つのエクステントが割り当てられ、エクステントの一部であり、動的に割り当てられませんでした。

+0

これらの2つのポインタを「解放」するには、 A [i] .hijo1 = NULL; A [i] .hijo2 = NULL; で十分でしょうか? –

+0

@ Luis_VそれらをNULLに設定することができます。また、例えばINIC_ARBOL関数は、このデータフィールドをノードの半分以下にしか設定しないことも考慮に入れてください。 –

+0

はい。私はいくつかの "hijo"ポインタを初期化する必要があります。親切なユーザーC: –

1

メモリ管理関数からもNULLポインタも返されないものを渡すか、未定義の動作を呼び出します。

機能FREE_ARBOL()から問題の一部を

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

を削除します。

1

ショートストーリー:あなたはcallocの1つしか持っていないので、freeの1つしか持たないようにしてください。

if(例:if (2*i + 1 < longitud))がINIC_ARBOLの中にあるため、配列内のハーフノードは何も指していません。 typedef Nodo *Arregloを完全に削除して残りのコードでNode*を使用すると、コードを読みやすくなります。

+0

ありがとう、アドバイスありがとう –