Определить буфер, выделенный с помощью malloc()

Есть ли способ определить, был ли буфер выделен 'malloc'? как функция со следующей сигнатурой:

bool is_malloced(void *buf);

Существует ли такой механизм в posix?

3 ответа

Неа. Ни C11, ни POSIX не обеспечивают такой механизм.


mmm, если вы серьезный человек, вы действительно можете:

Hash *hsh; /* global hash already initialized. */
void *custom_malloc(size_t size)
{
 void *ptr;
 ptr = malloc(size);
 hash_add(hsh, ptr);
 return ptr;
}
/* tester */
_Bool malloced(void *ptr)
{
 if(hash_retrieve(hsh, ptr))
 return TRUE;
 return FALSE;
}

Конечно, такая вещь - безумие, но действительно вы можете.


Один простой способ подражать такой функции - обернуть malloc() в пользовательскую функцию, которая:

  • выделяет буфер, который является, например, 4 байта больше
  • хранит некоторое магическое число (32 бит) в начале выделенного блока
  • увеличивает указатель на 4 байта, прежде чем возвращать его вызывающему абоненту

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

Конечно, это не идеально:

  • волшебное число может быть там случайно. Это может помочь установить его в null в завернутый вызов free(). XOR-ing с указателем и т.д. Также может сделать его более надежным. Тем не менее, это эвристика.
  • на архитектурах с защитой памяти вы можете вызвать ошибку страницы при проверке указателя, который не был указан malloc'ed.

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

Если мы собираемся заменить malloc() на некоторую оболочку, мы могли бы также построить связанный список выделенных блоков. Гораздо надежнее, но и сложнее.

licensed under cc by-sa 3.0 with attribution.