Ich versuche das zu verstehen sbrk()
Funktion.
Von dem was ich weiß:
sbrk(0)
gibt die aktuelle Adresse der Unterbrechung zurück und erhöht sie nicht.
sbrk(size)
erhöht die Adresse des Breaks um size
Bytes und gibt die vorherige Adresse des Breaks zurück.
Also habe ich etwas erstellt, um es zu testen:
#include <unistd.h>
#include <stdio.h>
int main(void)
{
printf("sbrk(0) = %p\n", sbrk(0)); // should return value x
printf("sbrk(0) = %p\n", sbrk(0)); // should return value x
printf("sbrk(5) = %p\n", sbrk(5)); // should return value x
printf("sbrk(0) = %p\n", sbrk(0)); // should return value x + 5
}
Ich erwarte also ein Ergebnis, das wie folgt aussieht:
sbrk(0) = 0x1677000 // x value
sbrk(0) = 0x1677000 // x value
sbrk(5) = 0x1677000 // x value
sbrk(0) = 0x1677005 // x value + 5
aber stattdessen bekomme ich das:
sbrk(0) = 0x1677000 // x value
sbrk(0) = 0x1698000 // y value
sbrk(5) = 0x1698000 // y value
sbrk(0) = 0x1698005 // y value + 5
Warum nicht die ersten beiden Anrufe von sbrk(0)
denselben Wert zurückgeben? Was passiert zwischen diesen beiden Aufrufen, die die Unterbrechungsadresse ändern?
BEARBEITEN :
Das Speichern von Adressen in Variablen löst das Problem:
int main(void)
{
void *toto1 = sbrk(0);
void *toto2 = sbrk(0);
void *toto3 = sbrk(5);
void *toto4 = sbrk(0);
printf("sbrk(0) = %p\n", toto1);
printf("sbrk(0) = %p\n", toto2);
printf("sbrk(5) = %p\n", toto3);
printf("sbrk(0) = %p\n", toto4);
}
printf
könnte etwas dynamisches Speichermaterial verwenden. Versuchen Sie stattdessen, die Werte Variablen zuzuweisen, und drucken Sie sie sofort aus.– Eugen Sch.
21. Januar 2019 um 17:09 Uhr
Dann aktualisieren Sie Ihre Frage bitte auch mit dem anderen Code, damit niemand diese Annahme wiederholt.
– Eugen Sch.
21. Januar 2019 um 17:24 Uhr
Sie müssen verwenden mehrere Variablen, und tun alle Anrufe zu
sbrk
vor dem Anrufprintf
. Ihr aktualisierter Code funktioniert im Grunde genauso wie der erste und wird das gleiche Problem haben.– Irgendein Programmierer-Typ
21. Januar 2019 um 17:32 Uhr
Mein erraten ist, dass die Initialisierung der Standard-E/A-Teile träge erfolgt. Das heißt, die Initialisierung erfolgt, wenn sie benötigt werden, und ein Teil dieser Initialisierung ist die Zuweisung des Puffers für
stdout
.– Irgendein Programmierer-Typ
21. Januar 2019 um 17:50 Uhr
Hier ist der Argumentbehandlungscode von glibc: github.com/bminor/glibc/blob/master/stdio-common/… Es ruft
malloc()
an einigen Stellen.– Rumpelsepp
21. Januar 2019 um 17:50 Uhr