2016-05-17 21 views
6

Devo allocare memoria per 4 puntatori ai puntatori su float (2D) su molte iterazioni (6), ma alla seconda iterazione, malloc mi dà lo stesso indirizzo per due allocazioni. Codice:risultati imprevisti per l'allocazione di memoria con la funzione c malloc

int i=0, a=0; 
for(i=0;i<6;i++) 
{ 
    float** P_i=(float**) malloc(4*sizeof(float*)); 
    for(a=0;a<4;a++) P_i[a]=(float*) calloc(4,sizeof(float)); 

    for(a=0;a<4;a++) free(P_i[a]); 
    free(P_i); 
} 

Debugging con gdb:

(gdb) print i 
$42 = 1 
(gdb) set $pos=0 
(gdb) print P_i[$pos++] 
$51 = (float *) 0x804d500 
(gdb) print P_i[$pos++] 
$52 = (float *) 0x804d148 
(gdb) print P_i[$pos++] 
$53 = (float *) 0x804d4e8 
(gdb) print P_i[$pos++] 
$54 = (float *) 0x804d500 

p_i [0] e p_i [3] puntare allo stesso indirizzo 0x804d500 e non riesco a trovare il motivo:/

+3

C o C++? L'uso di 'malloc' tende a suggerire C, ma lanciare il' void * 'restituisce è una cosa C++. Se stai usando C, non riesci a restituire 'malloc' e co_ –

+0

c. Ho provato a rimuovere il cast ma ottengo una conversione non valida da 'void *' a 'float *' – DahoM

+1

Che compilatore stai utilizzando? Se si lamentano dei valori di ritorno 'malloc', è probabile che si stia utilizzando un compilatore C++ –

risposta

2

tra il primo per (a = 0; a < 4; a ++) e il 2 ° (prima di liberare)

La mia ipotesi è che gdb interrompe l'ultima iterazione del ciclo, prima dell'ultima chiamata calloc(). Se è il caso P_i [3] avere l'indirizzo della precedente iterazione.

Btw, è difficile usare gdb quando c'è più di una dichiarazione per riga.

+0

L'interruzione viene impostata sulla linea vuota tra il ciclo 2 for, l'esecuzione si arresta proprio sull'istruzione free for loop (ma non avvia nemmeno il ciclo). Non ho ancora padroneggiato gdb, affatto! ma fino ad ora sono rimasto davvero impressionato dalla sua flessibilità. – DahoM

+0

Sospetto che questo sia il più vicino alla realtà. Il codice non _use_ 'P_i [3]' e alcune ottimizzazioni potrebbero essere in effetti facendo si che il break-point non sia nel codice dove sembra essere in soruce. – chux

1

Con le informazioni disponibili, non è possibile rispondere a questa domanda, ma consentitemi di provare.

Il codice sembra ok. Non riesco nemmeno a riprodurre il tuo problema.

Non è possibile inserire un punto di interruzione su una riga vuota. Immagino che lo metterebbe su una linea con libero.

Secondo la mia ipotesi, il codice è stato compilato con l'ottimizzazione abilitata, che probabilmente ha riordinato le cose per assicurarsi che non si sia veramente sicuri di dove l'esecuzione è stata interrotta. Disabilita ottimizzazione e ricostruzione (su GCC che sarebbe -0). Oppure mostraci lo smontaggio (incluso il PC corrente in cui stampi).

La mia corsa su Ubuntu gcc (Ubuntu 4.8.4-2ubuntu1 ~ 14.04.1) 4.8.4 costruito con -O0 -g, fermato su una linea di connessione (prima che fosse giustiziato):

(gdb) print i
$ 1 =
(gdb) set $ pos = 0
(gdb) print p_i [$ pos ++]
$ 2 = (float *) 0x602040
(gdb) print p_i [ $ pos ++]
$ 3 = (float *) 0x602060
(gdb) print p_i [$ pos ++]
$ 4 = (float *) 0x602080
(gdb) stampare p_i [$ pos ++]
$ 5 = (float *) 0x6020a0
(gdb) bt
# 0 main() presso malloc.c: 12
(gdb) Lista
7 per (i = 0; i < 6; i ++)
8 {
9 float ** p_i = (float **) malloc (4 * sizeof (float *));
10 per (a = 0; a < 4; a ++) P_i [a] = (float *) calloc (4, sizeof (float));
12 per (a = 0; a < 4; a ++) gratuito (P_i [a]);

Il codice sorgente presenta un problema anche se lo si genera separatamente (non una parte del programma più grande)? Avete implementato calloc/malloc personalizzato? Cosa mostra "nm your-executable | grep calloc"? Dovrebbe essere qualcosa di simile:

U calloc @@ GLIBC_2.2.5

+0

Grazie per il vostro aiuto. Sembra che io abbia una corruzione della memoria che appare da qualche parte dopo la prima iterazione. Sto scavando e inoltrerò al più presto. – DahoM

Problemi correlati