Ich habe diese Antwort auf einen ähnlichen Beitrag zum gleichen Thema gegeben:
Sind einige Allokatoren faul?
Dies beginnt ein wenig abseits des Themas (und dann werde ich es mit Ihrer Frage verknüpfen), aber was passiert, ähnelt dem, was passiert, wenn Sie einen Prozess unter Linux abspalten. Beim Gabeln gibt es einen Mechanismus namens Kopieren beim Schreiben, der den Speicherplatz für den neuen Prozess nur kopiert, wenn auch der Speicher geschrieben wird. Auf diese Weise haben Sie den Aufwand für das Kopieren des ursprünglichen Programmspeichers gespart, wenn der gegabelte Prozess sofort ein neues Programm ausführt.
Zurück zu Ihrer Frage: Die Idee ist ähnlich. Wie andere bereits betont haben, erhalten Sie durch das Anfordern des Speichers sofort den virtuellen Speicherplatz, aber die tatsächlichen Seiten werden nur beim Schreiben zugewiesen.
Was ist der Zweck davon? Grundsätzlich wird das Mallocing von Speicher zu einer mehr oder weniger konstanten Zeitoperation Big O (1) anstelle einer Big O (n) -Operation (ähnlich wie der Linux-Scheduler seine Arbeit verteilt, anstatt sie in einem großen Block auszuführen).
Um zu demonstrieren, was ich meine, habe ich folgendes Experiment durchgeführt:
rbarnes@rbarnes-desktop:~/test_code$ time ./bigmalloc
real 0m0.005s
user 0m0.000s
sys 0m0.004s
rbarnes@rbarnes-desktop:~/test_code$ time ./deadbeef
real 0m0.558s
user 0m0.000s
sys 0m0.492s
rbarnes@rbarnes-desktop:~/test_code$ time ./justwrites
real 0m0.006s
user 0m0.000s
sys 0m0.008s
Das BigMalloc-Programm weist 20 Millionen Ints zu, macht aber nichts damit. deadbeef schreibt ein int auf jede Seite, was zu 19531-Schreibvorgängen führt, und justwrites weist 19531 ints zu und setzt sie auf Null. Wie Sie sehen, dauert die Ausführung von Deadbeef etwa 100-mal länger als bei Bigmalloc und etwa 50-mal länger als bei Justwrites.
#include <stdlib.h>
int main(int argc, char **argv) {
int *big = malloc(sizeof(int)*20000000);
return 0;
}
.
#include <stdlib.h>
int main(int argc, char **argv) {
int *big = malloc(sizeof(int)*20000000);
for (int* end = big + 20000000; big < end; big += 1024)
*big = 0xDEADBEEF;
return 0;
}
.
#include <stdlib.h>
int main(int argc, char **argv) {
int *big = calloc(sizeof(int), 19531);
return 0;
}