2016-03-27 10 views
1

der Heap für das Aufspalten ist eine verkettete Liste von Strukturen der folgenden Definition:Ausführungs Malloc: Fall einen Block

struct block 
{ 
/*header + block*/ 
bool freeSpace; 
block * prev; 
block * next; 
size_t size; 
char block_part[]; 
}; 

ich auf folgenden Fall gerade arbeite:

Wenn der erste Block Speicher finde ich ist so groß, dass es sowohl den neu zugewiesenen Block als auch einen weiteren Block aufnehmen kann, dann wird der Block in zwei geteilt; ein Block, um den neu zugewiesenen Block und einen verbleibenden freien Block zu halten.

(Beachten Sie, dass, wenn es ein bisschen größer ist als das, was ich brauche, aber nicht groß genug für einen neuen Block (dh es ist nicht groß genug, die Metadaten eines neuen Blockes) zu halten, habe ich bei der ungenutzten Raum habe Ende des Blocks.)

Mein Code ist der folgende. Wenn ich speziell diesen Fall teste, stürzt mein Programm mit einem segfault ab. Könnte jemand sehen, was das Problem ist? Vielen Dank.

do{ 
    if (ptr -> freeSpace && ptr -> size >= size){ 
     /*first suffient free block is found*/ 
     ptr -> freeSpace = false; 

     if (ptr -> size > size + sizeof(struct block)){ 
      /*if big enought for 'size' AND metadata of a new block, split the block*/ 
      struct block * returnPtr = memset((ptr -> block_part), 0, size); 
      struct block * added = returnPtr + size; 
      added -> size = ptr -> size - size - sizeof(struct block); 
      added -> freeSpace = true; 
      added -> prev = ptr; 
      added -> next = ptr -> next; 
      (ptr -> next) -> prev = added; 
      ptr -> next = added; 
      ptr -> size = size; 
      return returnPtr; 

      } 
     ptr -> size = size; 
     return memset((ptr -> block_part), 0, size); 

     } 
    prevPtr = ptr; 
    ptr = ptr -> next; 


}while (ptr); 
+1

Sicherlich teilen Sie nur einen Block, wenn Sie keinen Block finden, der groß genug ist? Und bitte entfernen Sie die Leerzeichen auf jeder Seite der '->' –

+0

Das ist nicht, wenn ich geteilt habe. Ich spalte, wenn ich einen Block finde, der zu groß ist. @WeatherVane – Jobs

+0

Ich schlage vor, dass Sie die Größe der Metadaten der Speicheranforderung hinzufügen, bevor Sie beginnen. –

Antwort

2

Memset gibt ein void *. Es wird keine Warnung ausgegeben, da Void Pointer automatisch vom Compiler gecastet werden (z. B. malloc () non-).

struct block *returnPtr = memset((ptr->block_part), 0, size); 

Warum würden Sie Abfall Speicher für eine ganze Struktur mit mehreren Mitgliedern eine Lücke Zeiger auf Zeichen zu speichern?

Danach verwenden Sie die Adresse des jetzt void pointer und verschieben Sie es size -num vor. Danach behandle es wie eine zugewiesene Struktur. Das führt dazu, dass added überhaupt nicht zugewiesen wird (wenn size größer als strlen(ptr->block_part)+1 ist, sind Sie bereits auf dem Speicher eines anderen) oder zumindest verletzen Speicher. Der Zugriff auf einen solchen Speicher ergibt ein fehlerhaftes Programm.

Daher beobachten Sie Segmentierungsfehler und Sie Programmabstürze.


Hinweis: Bisher habe ich nicht, dass jemand in einer solchen Art und Weise der memset Rückgabewert verwenden gesehen.

+0

"Hinweis: Bisher habe ich noch nicht gesehen, dass jemand den Rückgabewert von memsets so verwendet" - ich habe das oft gelesen, aber es ist nichts falsch daran, wirklich, oder? – Jobs

+0

Willst du sagen, dass die Änderung von block * returnPtr zu char * returnPtr mein Problem löst? – Jobs

+1

Eigentlich, als ich es in char * geändert habe, funktioniert es jetzt !!!!! DANKE!!!!!!!!!!!!! – Jobs