Почему двойной вызов sbrk (0) дает другое значение? - PullRequest
0 голосов
/ 21 января 2019

Я пытаюсь понять функцию sbrk().

Из того, что я знаю:
sbrk(0) возвращает текущий адрес разрыва и не увеличивает его.
sbrk(size) увеличивает адрес разрыва на size байт и возвращает предыдущий адрес разрыва.

Итак, я создал что-то для проверки:

#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
}

Так что я ожидаю увидеть результат, похожий на этот:

sbrk(0) = 0x1677000 // x value
sbrk(0) = 0x1677000 // x value
sbrk(5) = 0x1677000 // x value
sbrk(0) = 0x1677005 // x value + 5

но вместо этого я получаю это:

sbrk(0) = 0x1677000 // x value
sbrk(0) = 0x1698000 // y value
sbrk(5) = 0x1698000 // y value
sbrk(0) = 0x1698005 // y value + 5

Почему первые два вызова sbrk(0) не возвращают одинаковое значение? Что происходит между этими двумя вызовами, которые изменяют адрес разрыва?

РЕДАКТИРОВАТЬ: Хранение адресов в переменных решает проблему:

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);
}

1 Ответ

0 голосов
/ 21 января 2019

Ваша программа выполняет следующую последовательность вызовов:

sbrk()
printf()
sbrk()
printf()
...

Первый вызов printf вызывает malloc внутренне для выделения буфера для stdout (stdout является буферизованной строкой по умолчанию, но буфер создается по требованию при первой печати на нем).

Вот почему второй вызов sbrk возвращает другое значение.

( Этот ответ не имеет прямого отношения, но сообщения об ошибках от valgrind раскрывают существование основного вызова malloc, скрытого внутри printf.)

Ваш второй пример выполняет все sbrk вызовы заранее, поэтому нет никаких сюрпризов от других функций, вызывающих malloc за вашей спиной.

...