面试题答案
一键面试设计思路
- 记录内存分配信息:在每次分配内存时,记录分配的内存地址、大小以及分配该内存的代码位置(如文件名、行号)。这可以通过自定义的数据结构来实现。
- 跟踪内存释放:每次释放内存时,从记录的分配信息中移除相应的记录。
- 检测内存泄漏:在程序结束或特定的检测点,检查记录的分配信息中是否存在未被释放的内存。如果存在,则表明发生了内存泄漏。
- 定位泄漏位置:对于检测到的内存泄漏,利用之前记录的代码位置信息,方便开发人员定位到具体的代码行。
关键实现步骤
- 定义数据结构:
typedef struct {
void *address;
size_t size;
const char *file;
int line;
struct MemoryRecord *next;
} MemoryRecord;
MemoryRecord *head = NULL;
- 修改内存分配函数:
void* my_malloc(size_t size, const char *file, int line) {
void *ptr = malloc(size);
if (ptr) {
MemoryRecord *newRecord = (MemoryRecord*)malloc(sizeof(MemoryRecord));
newRecord->address = ptr;
newRecord->size = size;
newRecord->file = file;
newRecord->line = line;
newRecord->next = head;
head = newRecord;
}
return ptr;
}
- 修改内存释放函数:
void my_free(void *ptr) {
MemoryRecord *current = head;
MemoryRecord *prev = NULL;
while (current) {
if (current->address == ptr) {
if (prev) {
prev->next = current->next;
} else {
head = current->next;
}
free(current);
free(ptr);
return;
}
prev = current;
current = current->next;
}
}
- 添加内存泄漏检测函数:
void detect_memory_leaks() {
MemoryRecord *current = head;
while (current) {
printf("Memory leak detected at %s:%d, address: %p, size: %zu\n",
current->file, current->line, current->address, current->size);
current = current->next;
}
}
- 使用宏方便调用:
#define my_malloc(size) my_malloc(size, __FILE__, __LINE__)
在程序结束前调用detect_memory_leaks
函数,即可检测并定位内存泄漏。