значение длины (целое число), используемое свободным указателем - PullRequest
0 голосов
/ 13 января 2012

Как мы знаем, функция free() знает, сколько памяти нужно освободить из памяти malloc, используя префиксное целочисленное значение, хранящееся сразу после указателя malloc.Поэтому я попробовал этот код и у меня есть два сомнения:

  1. Если я malloc() 20 байтов, а затем вывести целочисленное значение по уменьшенному указателю, он показывает 25 байтов.И если я malloc() 40 байт, а затем вывести значение, то я получу 49 байт!

  2. Если я попытаюсь выйти за пределы и распечатать значения после моего пробела malloc, каждыйвремя я получаю большое целочисленное значение, хранящееся рядом с последним из памяти malloc.Что это за значение?Это что-то особенное?

Любое объяснение будет оценено.

int main()
{
    int i;
    int *ptr, *pr;

    ptr = (int *)malloc(20);
    pr = ptr;

    printf("value of ptr is %p", ptr);
    for(i = 0; i < 5; i++) {
        ptr[i] = i + 1;
    }

    printf("now the values in malloc'd memory is\n");
    for(i = 0; i < 5; i++) {
        printf("%d\n", ptr[i]);
    }

    printf("value of ptr is %p\n", ptr);
    pr--;
    for(i = 0; i < 20; i++) {
        printf("value of pr at address  %p  is  %d\n", pr, *pr);
        pr++;
    }

    return 0;
}

Ответы [ 2 ]

2 голосов
/ 13 января 2012
  1. Мы не знаем, как внутренне работает malloc. Может меняться от версии к версии библиотеки времени выполнения. То, что у него нет (пока), это не повод для игры.

  2. Мы не должны зависеть от конкретного закулисного поведения какой-либо конкретной реализации. Зависит только от документированных функций, если только вы не готовы торговать общностью для каких-то достойных целей.

Большинство реализаций malloc фактически выделяют дополнительные несколько слов служебной информации непосредственно перед областью, данной программе. Накладные расходы позволяют администрировать кучу. Но размер поля 4 байта раньше или 16? Это 32-битное значение? Может быть, это уменьшенное количество абзацев (16-байтовые записи), как в iRMX86. Содержит ли служебная область прямые ссылки и обратные ссылки? Возможно, есть поле для проверки имен с отладочной версией библиотеки.

Может быть, он реализован как Snobol-68 в Cyber ​​/ NOS: массив структур с указателями на данные и их размеры. Программные «указатели» на самом деле являются индексами элемента в массиве. Это особенно эффективная структура для целей кэширования и чтения.

Существует так много возможных вариантов, что ни одна программа не должна полагаться на такие детали.

Возможно, вы могли бы подумать о написании функции lengthof(ptr) для включения в библиотеку времени выполнения, которая возвращает количество байтов, запрошенных в malloc(), или, возможно, фактически выделенных байтов.

0 голосов
/ 13 января 2012

Вероятно, в большинстве реализаций malloc есть какой-то способ найти выделенный размер аргумента указателя.

Однако способ сделать это является частным для реализации, а некоторые mallocРеализация не всегда выделяет префиксный заголовок для каждой зоны.

Обычный прием реализации malloc заключается в том, чтобы по-разному обрабатывать различные выделенные размеры.Например, он может обрабатывать по-разному

  1. malloc из двух слов или менее (т. Е. 2*sizeof(void*)), поскольку этот случай очень частый (например, для односвязного списка указателей, например * 1015).* ячейки в Лиспе).
  2. malloc зон малого размера, размер которых меньше порога, обычно размера страницы - в смысле системного вызова getpagesize (2) в Linux, часто 4 КБ.
  3. malloc зон большого размера, больше, чем размер страницы

В некоторых реализациях учитывается фактический адрес, например, при наличии внутренней арены (сегментыстраниц), предназначенных для пар, еще одна арена распределения, предназначенная для зон небольшого размера размером 2^n и 3*2^n (например, n>2 && n<10), и для больших объектов, фактически выделенных на их собственной арене каждая.Тогда у реализации malloc есть несколько адресов внутренних хеш-таблиц (каждый из младших 16 битов, каждый из которых равен нулю) в арены.

Поэтому не следует предполагать, что каждая зона с ошибками раньше имела издержки.Это может быть неправильно.Если вам нужно такое предположение, напишите свой собственный malloc эквивалент (или замену), используя вызовы операционной системы (например, mmap (2) в Linux).

...