2016-05-17 8 views
6

Ich muss Speicher für 4 Zeiger auf Zeiger auf Float (2D) über viele Iterationen (6) zuweisen, aber in der zweiten Iteration, malloc gibt mir die gleiche Adresse für zwei Zuordnungen. Code:unerwartete Ergebnisse für die Speicherzuweisung mit c Malloc-Funktion

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 mit 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] und P_i [3] auf die gleiche Adresse 0x804d500 zeigen, und ich kann nicht, warum finden:/

+3

C oder C++: Es sollte so etwas wie dieses? Der Gebrauch von 'malloc' neigt dazu, C vorzuschlagen, aber das' void * ', das es zurückgibt, zu werfen, ist eine C++ Sache. Wenn Sie C verwenden, wird die Rückgabe von "malloc" und co_ –

+0

nicht c. Ich habe versucht, die Besetzung zu entfernen, aber ich bekomme eine ungültige Konvertierung von 'void *' zu 'float *' – DahoM

+1

Welchen Compiler benutzen Sie? Wenn es sich beschweren über "malloc" Rückgabewerte zu werfen, nutzen Sie wahrscheinlich einen C++ Compiler –

Antwort

2

zwischen dem ersten für (a = 0; a < 4; a ++) und dem 2. (vor dem befreien)

Meine Vermutung ist, dass gdb bricht bei der letzten Iteration der Schleife vor dem letzten Calloc() auf. Wenn dies der Fall ist, haben P_i [3] die Adresse der vorherigen Iteration.

Übrigens ist es schwierig, gdb zu verwenden, wenn mehr als eine Anweisung pro Zeile vorhanden ist.

+0

Die Pause wird auf der Leerzeile zwischen der 2 for-Schleife gesetzt, die Ausführung stoppt direkt bei der free for-Schleife-Anweisung (aber startet nicht einmal die Schleife). Ich habe gdb noch gar nicht gemeistert! aber soweit bin ich wirklich beeindruckt von seiner Flexibilität. – DahoM

+0

Ich vermute, das ist der Realität am nächsten. Code verwendet _use_ 'P_i [3]' nicht und bestimmte Optimierungen können bewirken, dass der Break-Point nicht im Code ist, in dem er zu sein scheint. – chux

1

Mit verfügbaren Informationen kann dies nicht beantwortet werden, aber lass mich es versuchen.

Der Code scheint in Ordnung zu sein. Ich kann dein Problem auch nicht reproduzieren.

Sie können nicht wirklich einen Haltepunkt auf eine leere Zeile setzen. Ich schätze, das würde es auf eine Linie mit freien stellen.

Meine Vermutung ist, dass Ihr Code mit optimierter Optimierung kompiliert wurde, die wahrscheinlich Dinge neu geordnet hat, um sicherzustellen, dass Sie nicht wirklich sicher sind, wo die Ausführung gestoppt wurde. Deaktiviere Optimierung und baue neu (auf GCC, das wäre -O0). Oder zeigen Sie uns die Demontage (einschließlich aktueller PC, wo Sie drucken).

Mein Run auf Ubuntu gcc (Ubuntu 4.8.4-2ubuntu1 ~ 14.04.1) 4.8.4 gebaut mit -O0 -g, mit frei auf einer Linie gestoppt (bevor er ausgeführt wurde):

(gDB) print i
$ 1 =
(gDB) Set $ ​​pos = 0
(gDB) print P_i [$ pos ++]
$ 2 = (float *) 0x602040
(gDB) drucken P_i [ $ pos ++]
$ 3 = (float *) 0x602060
(gdb) print P_i [$ pos ++]
$ 4 = (float *) 0x602080
(GDB) drucken P_i [$ pos ++]
$ 5 = (float *) 0x6020a0
(GDB) bt
# 0 main() bei malloc.c: 12
(GDB) Liste
7 für (i = 0; i < 6; i ++) {
9 float P_i ** = (float **) malloc (4 * sizeof (float *));
10 für (a = 0; a < 4; a ++) P_i [a] = (float *) Calloc (4, sizeof (float));
12 für (a = 0; a < 4; a ++) frei (P_i [a]);

Gibt es in Ihrem Quellcode zeigt ein Problem, auch wenn Sie es separat bauen (kein Teil eines größeren Programms)? Verfügen Sie über ein benutzerdefiniertes Calloc/Malloc? Was zeigt "nm your-executable | grep calloc"?

U calloc @@ GLIBC_2.2.5

+0

Vielen Dank für Ihre Hilfe. Es scheint, dass ich eine Speicherbeschädigung irgendwo nach der ersten Iteration habe. Ich grabe und werde so schnell wie möglich weiterleiten. – DahoM