C 使用strdup后无法释放内存

C 使用strdup后无法释放内存,c,free,strdup,C,Free,Strdup,通用条款4.5.1 c89 我正在努力释放一些记忆。然而,当我检查valgrind时,内存还没有被释放。我想知道我做错了什么 我的结构如下: typedef struct tag_cand_results { char *candidate_winners[NUMBER_OF_CANDIDATES]; } cand_results; cand_results *results = NULL; 我创建此结构的对象: typedef struct tag_cand_results {

通用条款4.5.1 c89

我正在努力释放一些记忆。然而,当我检查valgrind时,内存还没有被释放。我想知道我做错了什么

我的结构如下:

typedef struct tag_cand_results {
    char *candidate_winners[NUMBER_OF_CANDIDATES];
} cand_results;
cand_results *results = NULL;
我创建此结构的对象:

typedef struct tag_cand_results {
    char *candidate_winners[NUMBER_OF_CANDIDATES];
} cand_results;
cand_results *results = NULL;
我为结构分配了一些内存

results = calloc(1, sizeof *results);
给它分配一些数据

results->candidate_winners[0] = strdup("Steve Martin");
results->candidate_winners[1] = strdup("Jack Jones");
然后我尝试释放所有分配的内存:

free(results->candidate_winners[0]);
free(results->candidate_winners[1]);
free(results);

Just to be safe assign to NULL
results = NULL;
我从valgrind获得以下输出

==8119== 72 bytes in 6 blocks are definitely lost in loss record 1 of 2
==8119==    at 0x4A05E46: malloc (vg_replace_malloc.c:195)
==8119==    by 0x3FE2E82A91: strdup (strdup.c:43)
==8119==    by 0x400E5A: main (driver.c:116)
==8119== 
==8119== 72 bytes in 6 blocks are definitely lost in loss record 2 of 2
==8119==    at 0x4A05E46: malloc (vg_replace_malloc.c:195)
==8119==    by 0x3FE2E82A91: strdup (strdup.c:43)
==8119==    by 0x400E72: main (driver.c:117)
我不知道为什么内存没有被释放

非常感谢您的建议,

如果这确实是事件的顺序,那么valgrind是错误的。内存正在被释放


至于您在评论中要求的最佳技巧,通常我会说valgrind,但在本例中可能不是:-)

有些东西需要检查

  • 如果只调用
    malloc(30)
    而不是
    strdup(一些字符串)
    (两种情况下),会发生什么
  • 一次删除一对
    (malloc或strdup)/free对,看看会发生什么
  • 我还没有看到您的实际代码,所以在每个
    strdup
    free
    行前后都放一个printf,以确保它们都在运行
  • 在这里发布一个完整的小程序(显示问题),以便我们可以检查它

值得一提的是,以下小型(完整)程序:

换句话说,没有问题。因此,在您的情况下,这可能是另一个问题(可能是环境问题)。这个特别的运行是在UbuntuLucid(10.04),GCC4.4.3,c89模式下完成的

我建议你在你的系统上输入这些代码,看看会发生什么。我用来编译和测试的命令行是:

gcc -std=c89 -o qq qq.c
valgrind ./qq

“6块72字节”,听起来不像“史蒂夫·马丁”或“杰克·琼斯”。您没有在某个点(!)覆盖指针?

分配/释放中没有明显的错误

看起来结果的内容已被某种方式更改(被某个野生指针覆盖?)

一种简单的检查方法是在使用strdup分配之后和释放之前立即打印指针的内存地址值(使用printf(“%p”,…)。如果它改变了:宾果

使用result也可以这样做,另一种解释可能是指向result的指针发生了变化(此后指向的值也发生了变化)

现在,如果指针确实发生了变化,那么如何确定它发生的位置呢

一种解决方案是使用调试器运行程序。在某些情况下,这可能非常耗时,但通常是有效的。但如果这不是一种选择,还有另一种方法。我通常发现它比使用调试器更快

在另一个变量中保留已分配指针的副本,最好使其远离内存块,内存块是损坏的指针(全局指针通常可以)

现在,在控制流中放入如下断言:

断言(结果==保存的结果)

在某个地方,断言应该失败,您最终会发现问题


之后,您不应该忘记删除不应该留在最终项目中的断言。为了确保这一点,只需删除保存的结果变量。如果保留任何断言,程序将不会在调试模式下编译。

您还可以使用gdb调试应用程序,并使用“watch”命令查看指针是否发生更改。在主函数上放置一个断点,并进行逐步跟踪,以发现问题所在

问候,


米格尔

你能不能把valgrind仍然以这种方式抱怨的最小的完整程序发布出来。在我的源代码中还有其他地方发生了一些事情。刚刚在下面的Pax上发布了一条评论。我只是将我的项目切换到另一个分支。我取出了所有不相关的代码,只有我实际分配内存的源代码。所以代码看起来就像我发布的一样。内存被释放。所以我认为在别的地方发生了一些事情。我需要进一步调查。但是,查找内存错误的最佳技术是什么?谢谢您提供的信息。我将检查我的源代码并报告任何新信息。谢谢