提问人:lbsmart 提问时间:3/3/2023 更新时间:3/3/2023 访问量:51
C 语言中 valgrind 的幻影泄漏
Phantom leaks with valgrind in C
问:
我正在编写一个简单的数组。我怎么想,在泄漏方面做正确的事。但 valgrind 不这么认为。为什么?那个幻影泄漏只是因为我做了更多的 malloc 然后免费?
法典:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CAPACITY_INCREACE(arr) ((int)(arr->capacity * 1.5f))
#define CAPACITY_DEFAULT 5
typedef struct array
{
int capacity;
int size;
int* arr;
} array;
array* create_array()
{
array* arr = (array*)malloc(sizeof(array));
arr->capacity = CAPACITY_DEFAULT;
arr->size = 0;
arr->arr = (int*)malloc(arr->capacity * sizeof(int));
return arr;
}
void print_array(array *arr)
{
printf("array, size - %d, capacity - %d\n", arr->size, arr->capacity);
for(int i = 0; i < arr->size; ++i)
printf("%d ", arr->arr[i]);
printf("\n");
}
void realloc_array(array* arr, int size)
{
int* new_arr = (int*)malloc(size * sizeof(int));
memcpy((void*)new_arr, arr->arr, arr->size * sizeof(int));
arr->arr = new_arr;
}
void add(array* arr, int element)
{
if((arr->size + 1) <= arr->capacity)
{
arr->arr[arr->size++] = element;
return;
}
arr->capacity = CAPACITY_INCREACE(arr);
realloc_array(arr, arr->capacity);
arr->arr[arr->size++] = element;
}
void delete_array(array *arr)
{
free(arr->arr);
free(arr);
}
int main(int argc, int** argv)
{
array* arr = create_array();
for(int i = 0; i < 8; i++)
add(arr, i);
print_array(arr);
delete_array(arr);
return 0;
}
Valgrind 运行和程序编译
gcc -g array.c && ./a.out
valgrind --leak-check=full -s ./a.out
来自 valgrind 的信息,他向我展示了哪里,但不幸的是我不明白我做错了什么:
HEAP SUMMARY:
in use at exit: 48 bytes in 2 blocks
total heap usage: 5 allocs, 3 frees, 1,128 bytes allocated
20 bytes in 1 blocks are definitely lost in loss record 1 of 2
by 0x10920B: create_array (array.c:21)
by 0x109443: main (array.c:71)
28 bytes in 1 blocks are definitely lost in loss record 2 of 2
by 0x10930C: realloc_array (array.c:43)
by 0x1093CD: add (array.c:57)
by 0x10946D: main (array.c:74)
LEAK SUMMARY:
definitely lost: 48 bytes in 2 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 0 bytes in 0 blocks
suppressed: 0 bytes in 0 blocks
答:
2赞
MikeCAT
3/3/2023
#1
函数
void realloc_array(array* arr, int size)
{
int* new_arr = (int*)malloc(size * sizeof(int));
memcpy((void*)new_arr, arr->arr, arr->size * sizeof(int));
arr->arr = new_arr;
}
在没有释放的情况下扔掉原始缓冲区。arr->arr
添加调用以避免内存泄漏。free()
void realloc_array(array* arr, int size)
{
int* new_arr = (int*)malloc(size * sizeof(int));
memcpy((void*)new_arr, arr->arr, arr->size * sizeof(int));
free(arr->arr); /* add this */
arr->arr = new_arr;
}
或使用标准.realloc()
void realloc_array(array* arr, int size)
{
int* new_arr = realloc(arr->arr, size * sizeof(int));
if (new_arr == NULL) exit(1);
arr->arr = new_arr;
}
另请注意,选择家庭结果被认为是一种不好的做法。malloc()
评论
0赞
Paul Floyd
3/3/2023
你必须在 C++ 中强制转换。问题是针对 C,我同意你不应该投射。不要混用 C 和 C++ - 它们共享传统并且相似,但这并不能使它们相同。
评论
malloc
比免费
多.这就是你的答案。如果你到最后还没记错,valgrind 会理所当然地抱怨。malloc
free
malloc
free
if((arr->size + 1) <= arr->capacity)
==>if( arr->size < arr->capacity )
...简单多了。