2017-01-31 11 views
-2

Перед началом области пользовательских данных в блоке памяти выделяется некоторое содержимое заголовка, выделенное с помощью malloc.Как изменить содержимое заголовка malloc.c?

buffer = (char*) (malloc (i)); 
int j; 
for(j=1;j<9;j++){ 
printf("before data: %d\n",*(buffer-j)); 

выход, что я получил это прежде чем данные: 0 прежде чем данные: 0 прежде чем данные: 0 прежде чем данные: 35 прежде чем данные: 0 прежде чем данные: 0 прежде чем данные: 0 прежде чем данные : 0

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

+5

Просто позвоните реальному 'malloc', чтобы выделить немного больше места, чем вам нужно, сохраните все, что хотите, в дополнительном пространстве и верните указатель на первый байт, который вы не использовали. (Требования к выравниванию соответствия). В 'free' или' realloc' вам необходимо соответствующим образом отрегулировать указатели. –

+0

Что вы хотите изменить в заголовке? Вы понимаете, что определение 'malloc()' не находится в файле заголовка, правильно? –

+0

@souravGhosh я загрузил библиотеку malloc.c, скомпилированную и связанную с существующими двоичными файлами – Fulan

ответ

1

Ваш код содержит неопределенное поведение при попытке получить доступ к памяти, которую вы не выделили. На данной платформе может случиться, что распределитель памяти помещает заголовок непосредственно перед выделенной памятью, но вы не можете полагаться на это.

Создайте свою собственную подпрограмму управления памятью, чтобы добавить больше пространства перед тем, как:

void *my_malloc(size_t s) 
    char *p = malloc(s+what_you_need); 
    if (p!=NULL) return (void *)(p+what_you_need); 
    return (void *)p; 
} 

void my_free(void *p) { 
    free(((char *)p)-what_you_need); 
} 

Вы также можете держать внимание на требования выравнивания.

+0

Должно быть 'return (char *) p + what_you_need;' поскольку '+' не определен в указателях 'void *' (даже если GCC имеет это расширение) –

+0

Правильно, я его изменю. –

+0

спасибо :) @ Jean-BaptisteYunès – Fulan

1

Если вы хотите заменить malloc, вы можете это сделать. Посмотрите, как это делается в tcmalloc и jemalloc, и сделайте это в своем собственном коде.

1

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

Это неправильный вариант или может быть неправильным в целом.

Умный malloc реализация часто обрабатывает разные блоки разных размеров. Иногда байты непосредственно перед зоной malloc не используются реализацией malloc.

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

В частности, некоторые реализации malloc обрабатывают выделение двух ячеек. Они могли бы определить (в своей реализации free) размер зоны, например. путем сравнения адресов. Например, malloc может быть закодирован с (упрощенной) гипотезой о том, что все адреса формы 0x10yyyyyy, где y - произвольная шестнадцатеричная цифра, представляют собой распределение кучек пар слов. Конечно, детали в нашей жизни намного сложнее, но вы получили идею: вычисление размера выделенной области кучи не обязательно должно использовать некоторые префиксные данные, это можно сделать другими способами.

И несколько вариантов использования malloc двухъядерных ячеек (очень часто используется для связанных списков или для Lisp «cons»).