Сколько байтов динамически выделяется в следующем сегменте кода?

Предполагая, что адрес памяти занимает 4 байта, а символ char занимает 1 байт:

char** t;
t = malloc(5 * sizeof(char*));
int i;
for (i = 0; i < 5; i++)
 t[i] = malloc(sizeof(char) * (i+1));

6 ответов

Решение

35 байт (смотрите разделение ниже)

char** t;
t = malloc(5 * sizeof(char*));  // 5 * 4 = 20 bytes
int i;
for (i = 0; i < 5; i++)
 t[i] = malloc(sizeof(char) * (i+1)); //1 + 2 + 3 + 4 + 5 = 15 bytes

Минимум около 35 байтов - но типичная реализация malloc будет иметь некоторый минимальный размер выделения, который он поддерживает, поэтому в действительности вы можете ожидать, что он будет использовать больше памяти, чем это (хотя, в точности, насколько больше будет варьироваться).

В типичном случае минимальное выделение будет примерно 16 или даже 32 байта, и в этом случае большинство размеров, указанных вами выше, на самом деле не будут иметь никакого значения - последние 5 выделений будут соответствовать минимальному значению. быть. В типичном случае размеры, превышающие этот, будут округлены до следующей степени 2.

Это дало бы 32 байта для вашего первого распределения и 16 или 32 (т. Е. Минимальный поддерживаемый размер) для каждого из остальных пяти элементов, что в сумме составляет 112 или 192 байта.

Пусть компьютер вычислит для вас:

char** t;
t = (char**) malloc(5 * sizeof(char*));
int i;
for (i = 0; i < 5; i++)
    t[i] = (char*) malloc(sizeof(char) * (i+1));

unsigned int sz = 5 * sizeof(char*);
for (i = 0; i < 5; i++)
    sz += sizeof(char) * (i+1);

printf("%d\n", sz);

Получите, сколько байтов выделено на вашей системе, например, с

#define malloc(s) mm(s)

void *mm(size_t s) {
    printf("allocating %d ...\n", (int)s);
    return (malloc)(s);
}

/* your code */

Конечно, вы можете суммировать размеры вместо того, чтобы печатать их.

35 на 32-битной машине.

20 за это

t = malloc(5 * sizeof(char*));

15 за это: 5+4+3+2+1

int i;
for (i = 0; i < 5; i++)
 t[i] = malloc(sizeof(char) * (i+1));

malloc() выделяет пространство, округленное до 16 байтов (по крайней мере, в win32), поэтому вы будете использовать 32 байта в первом выделении и 16*5 в цикле.

Существует также накладные расходы на malloc (как время, так и память), потому что malloc() ставит специальный заголовок, _CrtMemBlockHeader перед возвращением области памяти (именно поэтому вы должны дать точно такой же указатель на free() и могут использовать такие функции, как _msize(),

Таким образом, объем используемой памяти будет 32 + 80 = 112 байт. Учитывая также накладные расходы для заголовка: + 5 * sizeof(__CrtMemBlockHeader)

конечное количество может достигать 300 байт, что примерно в 8 раз больше ожидаемого 35.

Другие вопросы по тегам