Я знаю, что это старый вопрос, но почти все возможно в C. Здесь есть несколько хакерских решений, но правильный способ определить, правильно ли распределена память, - использовать оракул, чтобы занять место от malloc
, calloc
, realloc
, и free
. Точно так же тестовые среды (например, cmocka) могут обнаруживать проблемы памяти (seg-ошибки, а не освобождение памяти и т. Д.). Вы можете сохранить список адресов памяти, выделенных по мере их выделения, и просто проверить этот список, когда пользователь хочет использовать вашу функцию. Я реализовал что-то очень похожее для собственной платформы тестирования. Некоторые примеры кода:
typedef struct memory_ref {
void *ptr;
int bytes;
memory_ref *next;
}
memory_ref *HEAD = NULL;
void *__wrap_malloc(size_t bytes) {
if(HEAD == NULL) {
HEAD = __real_malloc(sizeof(memory_ref));
}
void *tmpPtr = __real_malloc(bytes);
memory_ref *previousRef = HEAD;
memory_ref *currentRef = HEAD->next;
while(current != NULL) {
previousRef = currentRef;
currentRef = currentRef->next;
}
memory_ref *newRef = (memory_ref *)__real_malloc(sizeof(memory_ref));
*newRef = (memory_ref){
.ptr = tmpPtr,
.bytes = bytes,
.next = NULL
};
previousRef->next = newRef;
return tmpPtr;
}
Вы бы аналогичные функции calloc
, realloc
и free
, каждая обертка с префиксом __wrap_
. Реальный malloc
доступен с использованием __real_malloc
(аналогично другим функциям, которые вы обертываете). Всякий раз, когда вы хотите проверить, действительно ли выделено память, просто перейдите по списку memory_ref
и найдите адрес памяти. Если вы найдете его, и он достаточно велик, вы точно знаете, что адрес памяти не приведет к сбою вашей программы; в противном случае вернуть ошибку. В заголовке файла ваша программа использует, вы бы добавить эти строки:
extern void *__real_malloc (size_t);
extern void *__wrap_malloc (size_t);
extern void *__real_realloc (size_t);
extern void *__wrap_realloc (size_t);
// Declare all the other functions that will be wrapped...
Мои потребности были достаточно просты, так что я реализовал очень простую реализацию, но вы можете себе представить, как это может быть расширена, чтобы иметь лучшую систему слежения (например, создать struct
, который отслеживает местоположение памяти в дополнение к размеру). Тогда вы просто компилировать код с
gcc src_files -o dest_file -Wl,-wrap,malloc -Wl,-wrap,calloc -Wl,-wrap,realloc -Wl,-wrap,free
Недостатком является то, что пользователь должен компилировать исходный код с вышеупомянутыми директивами; однако, это далеко не хуже того, что я видел. Есть некоторые накладные расходы на выделение и освобождение памяти, но при добавлении безопасности всегда возникают некоторые накладные расходы.
На самом деле я так не думаю, но я не чувствую себя достаточно уверенно, чтобы опубликовать его в качестве ответа. – Ibrahim
Невозможно проверить, если вы не используете диспетчер памяти или не сворачиваете свой собственный. –
Если его указатель на символ, мы можем сделать strlen() или sizeof() и проверить, сколько памяти выделено (конечно, если строка NULL завершена). Для других типов я не уверен, есть ли какой-то способ. !! –