为什么会发生这种内存泄漏
Why would this memory leak occur
我在 valgrind 中遇到这个错误
==399==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 240 byte(s) in 15 object(s) allocated from:
#0 0x7f2a8cfadb50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
#1 0x401371 in push /src/main.c:88
#2 0x401725 in buildTree /src/main.c:126
#3 0x4027e1 in encode /src/main.c:31
#4 0x402c8b in main /src/main.c:432
#5 0x7f2a8c761b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
我的推送功能:
void push(Heap* heap, Node* node) {
if (heap->heapSize + 1 >= heap->capacity) {
int capacity_ = heap->capacity * 2;
qNode** arr_ = realloc(heap->arr,sizeof(qNode) * capacity_);
heap->arr = arr_;
heap->capacity = capacity_;
}
heap->arr[heap->heapSize] = (qNode*) malloc(sizeof(qNode)); //line 88, where the leak occurs
heap->arr[heap->heapSize]->data = node;
heap->arr[heap->heapSize]->priority = node->count;
heap->heapSize = heap->heapSize + 1;
for (int i = (heap->heapSize/2)-1; i > -1; i--) {
heapify(heap, i);
}
}
我不明白为什么会发生泄漏,因为在程序结束时我清除了整个堆->arr
void freeHeap(Heap* heap) {
for (int i = 0; i < heap->heapSize; i++) {
freeTree(heap->arr[i]->data);
free(heap->arr[i]);
}
free(heap->arr);
free(heap);
}
当你在你的完整程序中看到 运行 pop() 时,指向之前由 heap->arr[0] 指向的 qNode 的唯一指针在 return 值中传回来自 pop().
qNode* pop(Heap* heap)
{
qNode* result = heap->arr[0];
heap->arr[0] = heap->arr[heap->heapSize - 1];
heap->heapSize = heap->heapSize - 1;
heapify(heap, 0);
return result;
}
这意味着 pop() 的调用者现在持有指向该 qNode 的最后一个指针,并且有义务确保在指针超出范围之前释放 qNode。
您的代码中有几个地方 pop() 的调用者没有做到这一点。这是来自 buildTree 的示例(显示的最后一行)。 qNode 在 buildTree returns 时泄漏,因为现在不再有任何指向该 qNode 的指针。
Node* buildTree(Heap* heap, int* tab) {
for (int i = 0; i < 256; ++i) {
if (tab[i]) {
Node* node = createNode(tab[i], i, NULL, NULL);
push(heap, node);.
}
}
if (heap->heapSize == 1) {
return pop(heap)->data;
我在 valgrind 中遇到这个错误
==399==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 240 byte(s) in 15 object(s) allocated from:
#0 0x7f2a8cfadb50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
#1 0x401371 in push /src/main.c:88
#2 0x401725 in buildTree /src/main.c:126
#3 0x4027e1 in encode /src/main.c:31
#4 0x402c8b in main /src/main.c:432
#5 0x7f2a8c761b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
我的推送功能:
void push(Heap* heap, Node* node) {
if (heap->heapSize + 1 >= heap->capacity) {
int capacity_ = heap->capacity * 2;
qNode** arr_ = realloc(heap->arr,sizeof(qNode) * capacity_);
heap->arr = arr_;
heap->capacity = capacity_;
}
heap->arr[heap->heapSize] = (qNode*) malloc(sizeof(qNode)); //line 88, where the leak occurs
heap->arr[heap->heapSize]->data = node;
heap->arr[heap->heapSize]->priority = node->count;
heap->heapSize = heap->heapSize + 1;
for (int i = (heap->heapSize/2)-1; i > -1; i--) {
heapify(heap, i);
}
}
我不明白为什么会发生泄漏,因为在程序结束时我清除了整个堆->arr
void freeHeap(Heap* heap) {
for (int i = 0; i < heap->heapSize; i++) {
freeTree(heap->arr[i]->data);
free(heap->arr[i]);
}
free(heap->arr);
free(heap);
}
当你在你的完整程序中看到 运行 pop() 时,指向之前由 heap->arr[0] 指向的 qNode 的唯一指针在 return 值中传回来自 pop().
qNode* pop(Heap* heap)
{
qNode* result = heap->arr[0];
heap->arr[0] = heap->arr[heap->heapSize - 1];
heap->heapSize = heap->heapSize - 1;
heapify(heap, 0);
return result;
}
这意味着 pop() 的调用者现在持有指向该 qNode 的最后一个指针,并且有义务确保在指针超出范围之前释放 qNode。
您的代码中有几个地方 pop() 的调用者没有做到这一点。这是来自 buildTree 的示例(显示的最后一行)。 qNode 在 buildTree returns 时泄漏,因为现在不再有任何指向该 qNode 的指针。
Node* buildTree(Heap* heap, int* tab) {
for (int i = 0; i < 256; ++i) {
if (tab[i]) {
Node* node = createNode(tab[i], i, NULL, NULL);
push(heap, node);.
}
}
if (heap->heapSize == 1) {
return pop(heap)->data;