2017-02-14 2 views
0

Während einige Zeiger freigeben, erhalte ich eine Zugriffsverletzung.
Um zu wissen, was los ist, habe ich beschlossen, die Zeiger zu einem früheren Zeitpunkt im Code freizugeben, auch direkt nach dem Speicher zugewiesen wurde, und immer noch stürzt es ab.
Es bedeutet, dass etwas ernsthaft falsch in der Art ist, wie meine Strukturen im Speicher gehandhabt werden.Warum die Zugriffsverletzung Ausnahme beim Freigeben direkt nach dem Zuweisen von Speicher

Ich weiß, dass in einer früheren Version des Codes gab es ein Schlüsselwort vor der Definition einiger Variablen, aber das Schlüsselwort ist verloren (es war Teil einer #define Klausel, die ich nicht zurück finden kann).

Weiß jemand, was in diesem Code falsch ist oder was das genannte Schlüsselwort sein sollte?

typedef unsigned long longword; 
typedef struct part_tag { struct part_tag *next; 
           __int64 fileptr; 
           word needcount; 
           byte loadflag,lock; 
           byte partdat[8192]; 
           } part; 

static longword *partptrs; 

<keyword> part *freepart; 
<keyword> part *firstpart; 

void alloc_parts (void) { 
    part *ps; 
    int i; 

    partptrs = (longword*)malloc (number_of_parts * sizeof(longword)); // number... = 50 
    ps = (part*)&freepart; 

    for (i=0; i<number_of_parts; i++) { 
    ps->next = (struct part_tag*)malloc(sizeof(part)); 
    partptrs[i] = (longword)ps->next; 
    ps = ps->next; 
    ps->fileptr = 0; ps->loadflag = 0; ps->lock = 0; ps->needcount = 0; // fill in "ps" structure 
    }; 
    ps->next = nil; 
    firstpart = nil; 
    for (i=0; i<number_of_parts; i++) { 
    ps = (part*)partptrs[i]; 
    free(ps); <-- here it already crashes at the first occurence (i=0) 
    }; 

} 

Vielen Dank im Voraus

In der Kommentare jemand fragt, warum ich Zeiger direkt nach ihnen die Zuweisung zu befreien. Dies ist nicht, wie das Programm ursprünglich geschrieben wurde, aber um zu wissen, was die Zugriffsverletzung verursacht, die ich in diesem Stil umgeschrieben habe.
Ursprünglich:

alloc_parts(); 
<do the whole processing> 
free_parts(); 

Um die Zugriffsverletzung zu analysieren ich die alloc_parts() Funktion in den Quellcode-Auszug angepasst habe ich es geschrieben habe. Der springende Punkt ist, dass selbst nach dem Zuweisen von Speicher die Freigabe fehlgeht. Wie ist das überhaupt möglich?

In der Zwischenzeit habe ich ein anderes seltsames Phänomen beobachtet:
Beim Zuweisen des Speichers scheinen die Werte von ps "vollständige" Adresswerte zu sein. Beim Versuch, den Speicher freizugeben, enthalten die Werte ps nur die letzten Ziffern der Speicheradressen.

Example of complete address :  0x00000216eeed6150 
Example of address in freeing loop : 0x00000000eeed6150 // terminating digits are equal, 
                 // so at least something is right :-) 

Dieses Problem wurde durch die longword Art verursacht: es scheint, dass diese Art zu klein war Adressen gesamte Speicher zu halten. Ich habe dies durch einen anderen Typ (unsigned long long) ersetzt, aber das Problem besteht immer noch. Schließlich

+0

Was ist 'Langwort'? Bitte [poste ein * vollständiges * Beispiel.] (Http://stackoverflow.com/help/mcve) –

+0

Was ist 'longword'? Warum ordnen Sie 'number_of_parts * longwords' Bytes statt z. 'number_of_parts * sizeof (part)'? Und am wichtigsten, warum benutzen Sie '& freepart', das Ihnen einen Zeiger * auf den Zeiger * gibt? –

+1

Das ist sehr schlechter Code, es behandelt Zeiger als Ganzzahlen.Wenn diese unterschiedliche Größen haben, ist es ein Genuss. Schreiben Sie es ohne das seltsame Wort "Langwort" um. – unwind

Antwort

0

, nach einer langen Zeit des Elends, ist das Problem gelöst:

Das Programm wurde ursprünglich als 32-Bit-Anwendung gemeint, was bedeutet, dass die ursprüngliche Art unsigned long ausreichen Speicheradressen zu halten.

Allerdings wird dieses Programm kompiliert nun als 64-Bit-Anwendung, daher die genannte Art nicht mehr ausreichend groß ist, 64-Bit-Speicheradressen zu halten, daher hat eine andere Art zur Lösung dieses Problems verwendet:

typedef intptr_t longword; 

Dies löst das Problem.

@Andrew Henle: Entschuldigung, ich wusste nicht, dass Ihr Kommentar die tatsächliche Lösung für dieses Problem enthielt.

Verwandte Themen