Warum hat malloc reservieren Sie eine andere Anzahl von bytes als angefordert?
Ich habe dieses Stück code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
int main(){
void *a, *b;
a = malloc(16);
b = malloc(16);
printf("\n block size (for a): %p-%p : %li", b, a, b-a);
a = malloc(1024);
b = malloc(1024);
printf("\n block size (for a): %p-%p : %li", b, a, b-a);
}
Sollte nicht dieser Druck den letzten zugeordneten block Größe (16 oder 1024)? Stattdessen druckt 24 und 1032, also die Menge an Speicher zu haben scheint 8 extra bytes.
Mein problem ist (bevor das test-Fall), dass ich malloc()
in einer Funktion (1024 bytes), und die Rückgabe der zugewiesenen Ergebnis. Bei der überprüfung der Blockgröße auf die Funktion zurückgeben, die ich bekommen 516 Blöcke... und ich verstehe nicht, warum. Ich denke, das könnte der Grund für die Beschädigung des Speichers, der Auftritt, nachdem ich einige Verarbeitung auf den zugewiesenen Puffer:)
Edit: ich habe gesehen Wie kann ich die Größe eines Arrays von einem Zeiger in C? und scheint zu Fragen, die gleiche Sache, sorry für die Umbuchung.
Habe ich wiederholt mein Beispiel zu meinem spezifischen code:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
short int * mallocStuff(long int number, short int base){
short int *array;
int size=1024;
array=(short int*)calloc(1,size);
//array=(short int*)malloc(size);
return array;
}
int main(){
short int **translatedArray;
translatedArray=malloc(4*sizeof(short int));
int i;
for(i=0;i<4;i++){
translatedArray[i]=mallocStuff(0,0);
if(i>0)
printf("\n block size (for a): %p-%p : %i",
translatedArray[i], translatedArray[i-1], translatedArray[i]-translatedArray[i-1]);
}
return 0;
}
Und der Ausgang ist
block size (for a): 0x804a420-0x804a018 : 516
block size (for a): 0x804a828-0x804a420 : 516
block size (for a): 0x804ac30-0x804a828 : 516
Gemäß den obigen post, das größer ist als 1024. Bin ich falsch?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie einen Fehler. Statt:
Sollten Sie
Hinweis: die fehlenden Zeiger in Ihrem code. Ich vermute, dies ist, wo Ihr beobachtete Verhalten ergibt sich aus.
Beachten Sie auch, dass
0x804a420 - 0x804a018 = 1032
, nicht516
. Die FormeltranslatedArray[i] - translatedArray[i - 1]
gibt Sie die Anzahl der Elemente (short ints, oder einfach, shorts) in zwischen den beiden Adressen, nicht die Anzahl der bytes.Erste, Malloc gibt keine Garantien, dass zwei aufeinanderfolgenden malloc-Aufrufe zurück aufeinanderfolgenden Zeigern.
Sekunde, abhängig von der jeweiligen Architektur, verschiedenen alignment-Regeln anwenden; manchmal werden Sie vielleicht Fragen, für ein einzelnes byte, sondern die Architektur bevorzugt Zuweisungen auf 8 - oder 4-byte-Abständen.
Dritte, malloc braucht einigen Aufwand, um zu speichern, wie groß der reservierte block, etc.
Nicht machen Annahmen darüber, was malloc tut dem vorbei, was die Dokumentation sagt!
Den
malloc
- Funktion weist immer etwas mehr als Sie verlangen, um zu speichern einige historische Angaben. Nach allem, wenn Sie anrufenfree()
es braucht, um zu wissen, wie groß der block ist.Auch, in der Regel
malloc
Implementierungen Runde die angeforderte Größe, die bis auf das nächste Vielfache von 8 oder 16 oder eine andere round-ish-Nummer.Update: Die eigentliche Antwort auf Ihre Frage liegt in Ihrer Nutzung der
short int
geben. Wenn dabei die Zeiger-Arithmetik (Subtraktion) zwischen typisierte Zeiger, C und C++ zurück, der Unterschied in der Anzahl Dinge hinwies. Da Sie zeigenshort int
, das ist zwei bytes groß ist, ist der zurückgegebene Wert ist die Hälfte von dem, was Sie erwarten.Auf der anderen Seite
malloc
weist immer eine bestimmte Anzahl von bytes, egal, was du wirkst, das Ergebnis danach. Versuchen Sie dies:Gibt es keine Garantien, dass zwei malloc-Aufrufe Rückkehr Blöcke genau zusammen verpackt - in der Tat gibt es keine Garantien für das Ergebnis, außer, dass, wenn es ungleich NULL sein, es wird an einen block mindestens so groß wie gewünscht.
Innen, mallocs halten, arbeiten, Daten, Ihnen zu helfen, verwalten heap. Zum Beispiel, die 8 bytes enthalten zwei Zeiger - ein Hinweis auf den nächsten block, und die andere zeigt den vorherigen block an. Ich weiß nicht, was diese 8 Byte sind, weil Sie nicht erwähnt, welches Betriebssystem Sie verwenden, aber es ist völlig normal für malloc zu verwenden, einige Speicher für sich selbst hinter den kulissen.
Einige allocators (z.B. auf windows) stellen eine library-Funktion, um zu entdecken, block-Größe, die gegeben wird, einen Zeiger, einige jedoch nicht, da es eine eher esoterische Funktion.
Was malloc zurückgibt, hängt von der Implementierung von malloc und die Architektur. Wie andere schon gesagt haben, Sie werden garantiert, um MINDESTENS die angeforderte Menge Speicher, oder NULL. Dies ist auch der Grund, warum manchmal können Sie schreiben über das Ende eines array, und nicht einen "segmentation fault". Es ist, weil Sie eigentlich zu TUN haben einen gültigen Zugriff auf den Speicher, Sie wusste es nicht.
malloc() ist in der Regel umgesetzt durch Aufteilung der verfügbaren heap in Blöcken von verschiedenen Größen. In Ihrem Fall, malloc() gibt 2 aufeinanderfolgenden 1024 (oder 16) byte-Blöcken. Die 8 byte Speicherplatz, die Sie erwähnen, wird von malloc() für die Buchhaltung Informationen.
Sehen, Doug Lea ' s malloc() impl Noten hier, um zu verstehen, was Los ist hinter den kulissen: http://g.oswego.edu/dl/html/malloc.html
malloc()
wird über einen eigenen overhead.Nicht zu erwähnen, dass es keine Garantie gibt, dass 2 aufeinander folgende Zuweisungen werden neben einander zu beginnen.
Wenn
malloc
gibt etwas anderes als null, dann wird der Speicher, der es zugewiesen wurde für Ihr Programm hat die Größe, die Sie übergebenmalloc
. Nehmen Sie den Mauszeiger Unterschied zwischen der return-Werte von zwei Unterschied Anrufe zumalloc
könnte einen beliebigen Wert haben, und hat nichts (naja wenig) zu tun, mit der block-Größe von der ersten zugewiesenen block.Fand ich dieses..und überprüfen Sie den link unten für mehr info.
Zuordnung
Einem block zugeordnet wird, die aus dem freien pool, indem zuerst die angeforderten bytes zu einem index-in dem bucket-array unter Verwendung der folgenden Gleichung:
benötigt = ersuchte + 8
Falls erforderlich <= 16,
dann
Eimer = 0
Wenn nötig > 16,
dann
Eimer = (log(gebraucht)/log(2) gerundet auf die nächste Ganzzahl) - 3
Die Größe der einzelnen Blöcke in der Liste verankert durch die Eimer-block-Größe = 2 Eimer + 4. Wenn die Liste im Eimer ist null, Arbeitsspeicher zugewiesen wird, mit dem sbrk Unterroutine zum hinzufügen von Blöcken auf der Liste. Wenn die block-Größe ist weniger als eine Seite, dann eine Seite zugewiesen wird mit dem sbrk Unterprogramm, und die Anzahl von Blöcken angekommen sind bei durch die Aufteilung der block-Größe die Größe der Seite in die Liste Hinzugefügt. Wenn die block-Größe ist gleich oder größer als eine Seite benötigt Arbeitsspeicher zugewiesen wird, mit dem sbrk subroutine und einem block Hinzugefügt wird zu der freien Liste für den Eimer. Wenn die freie Liste nicht leer ist, wird der block am Kopf der Liste an den Aufrufer zurückgegeben wird. Den nächsten block in der Liste wird dann die neue Brust.
http://publib.boulder.ibm.com/infocenter/systems/index.jsp?topic=/com.ibm.aix.genprogc/doc/genprogc/sys_mem_alloc.htm
Bevor der Zeiger steht, die Größe der folgenden array, das ist ein 32/64-bit-integer (weiß nicht, ob Sie signiert oder unsigniert)
, so dass die Menge des Arbeitsspeichers zu haben scheint 8 zusätzlichen bytes ?
malloc()
Umsetzung auf Ihrem system scheint zu reservieren, zusätzliche bytes zur Aufrechterhaltung meta-Daten wie wie groß heap Abschnitt ist, was ab Adresse etc-info.Obwohl seine variiert auf verschiedenen Plattformen.
Auf meinem X86-Systeme
malloc()
Zuteilung min17
bytes, auch wenn ich ersuchendenmalloc(0)
.malloc() können reservieren zusammenhängender Speicher Speicher, aber wenn dein Aufruf von malloc() 2 mal und kann nicht erwarten, dass Speicher reserviert werden zusammenhängend durch die Subtraktion von zwei Zeigern variabls...
Allerdings zugewiesenen Speicher ist virtueller Speicher ist ein Teil der kernel-Implementierung, Speicher-management(VFS), um genau zu sein. Es kann keinen Einfluss auf die Funktionalität der Anwendung.