我有二次多项式系数的结构。我声明了这个结构类型的变量,我读取了系数的值,然后我创建并初始化了一个指向这个结构的指针。然后我使用我的struct和指向struct变量的指针显示系数的值。最后,我将指向struct的指针设置为NULL并释放它。
然而,valgrind检测到内存泄漏,在我的生活中,我不能理解为什么。你能帮我理解吗?
valgrind ./polynome --leak-check=full
==11046== Memcheck, a memory error detector
==11046== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==11046== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==11046== Command: ./polynome --leak-check=full
==11046==
2 3 4
pCoeff: a = 2.000000, b = 3.000000, c = 4.000000
coeff: a = 2.000000, b = 3.000000, c = 4.000000
==11046==
==11046== HEAP SUMMARY:
==11046== in use at exit: 24 bytes in 1 blocks
==11046== total heap usage: 1 allocs, 0 frees, 24 bytes allocated
==11046==
==11046== LEAK SUMMARY:
==11046== definitely lost: 24 bytes in 1 blocks
==11046== indirectly lost: 0 bytes in 0 blocks
==11046== possibly lost: 0 bytes in 0 blocks
==11046== still reachable: 0 bytes in 0 blocks
==11046== suppressed: 0 bytes in 0 blocks
==11046== Rerun with --leak-check=full to see details of leaked memory
==11046==
==11046== For counts of detected and suppressed errors, rerun with: -v
==11046== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
这是我的C程序:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
double a;
double b;
double c;
} Coefficient;
int main() {
Coefficient *pCoeff = NULL;
Coefficient coeff;
scanf("%lf %lf %lf", &coeff.a, &coeff.b, &coeff.c);
pCoeff = (Coefficient *)malloc(sizeof(Coefficient));
if (pCoeff == NULL) {
fprintf(stderr, "Memory allocation error.\n");
exit(1);
}
pCoeff = &coeff;
printf("pCoeff: a = %lf, b = %lf, c = %lf\n", pCoeff->a, pCoeff->b, pCoeff->c);
printf(" coeff: a = %lf, b = %lf, c = %lf\n", coeff.a, coeff.b, coeff.c);
pCoeff = NULL;
free(pCoeff);
return 0;
}
答案 0 :(得分:2)
第一个问题在于以下语句,它与代码的作用不一致:
然后我创建并初始化一个指向这个结构的指针
请记住,变量pCoeff
是指针,即它存储地址。
在第
行
pCoeff = (Coefficient *)malloc(sizeof(Coefficient));
您存储在pCoeff
新动态分配结构的地址中。接下来,在行
pCoeff = &coeff;
您在pCoeff
(覆盖之前的值)中存储静态分配的结构coeff
的地址。这样做会丢失对动态分配的内存的唯一引用,从而导致内存泄漏。
实际复制结构的值的正确解决方案是使用memcpy
函数,或
*pCoeff = coeff;
第二个问题在于解除分配期间的陈述顺序。
在第
行pCoeff = NULL;
您存储在pCoeff
(覆盖之前的值)NULL 地址。这样做,您将再次失去唯一的引用并导致内存泄漏。
然后,在行
free(pCoeff);
您使用free
中存储的值调用pCoeff
。由于该值现在为NULL
,因此该函数不执行任何操作。
正确的释放序列将使两个语句的顺序相反:
pCoeff = NULL;
free(pCoeff);
变量coeff
似乎是多余的,因为您动态分配相同的类型并复制值。您可以先分配,然后直接读取pCoeff
指向的内存。
例如:
Coefficient *pCoeff = NULL;
pCoeff = (Coefficient *)malloc(sizeof(Coefficient));
if (NULL == pCoeff) {
fprintf(stderr, "Memory allocation error.\n");
exit(1);
}
scanf("%lf %lf %lf", &pCoeff->a, &pCoeff->b, &pCoeff->c);
/* TODO: Check the return value of scanf. */
printf("pCoeff: a = %lf, b = %lf, c = %lf\n", pCoeff->a, pCoeff->b, pCoeff->c);
...
答案 1 :(得分:1)
你的问题是这些代码行合起来没有意义:
Coefficient *pCoeff = NULL;
Coefficient coeff;
// this points pCoeff at a malloc()'d structure
pCoeff = (Coefficient *)malloc(sizeof(Coefficient));
// this points pCoeff at the structure on the stack - and
// leaks the one malloc()`d above
pCoeff = &coeff;
pCoeff = NULL;
// free() of a NULL pointer does nothing
free(pCoeff);
malloc()
然后free()
Coefficient
结构,或使用堆栈上的那个。你不需要同时做这两件事。