自定义free函数未完全释放内存,Valgrind报告‘still reachable’问题求助
自定义free函数未完全释放内存,Valgrind报告‘still reachable’问题求助
各位好,我最近跟着一篇文章实现了简化版的malloc和free,想通过Valgrind验证正确性,于是在两个函数里分别加了VALGRIND_MALLOCLIKE_BLOCK(block, size, 0, 0);和VALGRIND_FREELIKE_BLOCK(block, 0);。Valgrind确实能正确追踪内存分配动作,但程序退出时总有一个块被标记为still reachable,具体的Valgrind输出如下:
HEAP SUMMARY: ==74425== in use at exit: 20 bytes in 1 blocks ==74425== total heap usage: 2 allocs, 2 frees, 1,044 bytes allocated ==74425== ==74425== 20 bytes in 1 blocks are still reachable in loss record 1 of 1 ==74425== ==74425== LEAK SUMMARY: ==74425== definitely lost: 0 bytes in 0 blocks ==74425== indirectly lost: 0 bytes in 0 blocks ==74425== possibly lost: 0 bytes in 0 blocks ==74425== still reachable: 20 bytes in 1 blocks ==74425== suppressed: 0 bytes in 0 blocks
文章里在union结构体里加了个固定16字节的stub成员,但其实没必要,因为我这边sizeof(header_t)计算出来是24字节。下面是我的核心实现代码:
#include <pthread.h> #include <unistd.h> #include <stdio.h> // 注:header_t的定义在单独头文件中,包含状态union、size、is_free、next等成员 pthread_mutex_t global_malloc_lock; header_t *head, *tail; header_t *get_free_block(size_t size) { header_t *curr = head; while (curr) { if (curr->s.is_free && curr->s.size >= size) { return curr; } curr = curr->s.next; } return NULL; } void *my_malloc(size_t size) { size_t total_size; void *block; header_t *header; if (!size) { return NULL; } pthread_mutex_lock(&global_malloc_lock); header = get_free_block(size); if (header) { header->s.is_free = 0; pthread_mutex_unlock(&global_malloc_lock); return (void*)(header+1); } total_size = sizeof(header_t) + size; block = sbrk(total_size); if (block == (void*) -1) { pthread_mutex_unlock(&global_malloc_lock); return NULL; } header = block; header->s.is_free = 0; header->s.size = size; header->s.next = NULL; if (!head) { head = header; } if (tail) { tail->s.next = header; } tail = header; pthread_mutex_unlock(&global_malloc_lock); VALGRIND_MALLOCLIKE_BLOCK(block, size, 0, 0); return (void*)(header+1); } void my_free(void* block) { header_t *header, *tmp; void *programbreak; if (!block) { return; } pthread_mutex_lock(&global_malloc_lock); header = (header_t*)block - 1; programbreak = sbrk(0); if ((char*)block + header->s.size == programbreak) { if (head == tail) { head = tail = NULL; } else { tmp = head; while(tmp) { if (tmp->s.next == tail) { tmp->s.next = NULL; tail = tmp; } tmp = tmp->s.next; } } sbrk(0 - sizeof(header_t) - header->s.size); pthread_mutex_unlock(&global_malloc_lock); VALGRIND_FREELIKE_BLOCK(block, 0); return; } header->s.is_free = 1; pthread_mutex_unlock(&global_malloc_lock); }
测试用的main函数很简单:
int main(int argc, char const *argv[]) { printf("sizeof(header_t) = %zu\n", sizeof(header_t)); int* block = my_malloc(5*sizeof(int)); my_free(block); return 0; }
我现在困惑的点是:明明已经调用了my_free(),也用VALGRIND_FREELIKE_BLOCK()告诉Valgrind这块内存被释放了,为什么还是会出现still reachable的标记?是sbrk()没有真正把内存还给系统,还是我的free逻辑里有什么遗漏的地方?
内容来源于stack exchange
相关产品推荐
相关产品推荐

