C 使用strdup后无法释放内存
通用条款4.5.1 c89 我正在努力释放一些记忆。然而,当我检查valgrind时,内存还没有被释放。我想知道我做错了什么 我的结构如下: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 {
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
行前后都放一个printf,以确保它们都在运行free
- 在这里发布一个完整的小程序(显示问题),以便我们可以检查它
值得一提的是,以下小型(完整)程序: 换句话说,没有问题。因此,在您的情况下,这可能是另一个问题(可能是环境问题)。这个特别的运行是在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上发布了一条评论。我只是将我的项目切换到另一个分支。我取出了所有不相关的代码,只有我实际分配内存的源代码。所以代码看起来就像我发布的一样。内存被释放。所以我认为在别的地方发生了一些事情。我需要进一步调查。但是,查找内存错误的最佳技术是什么?谢谢您提供的信息。我将检查我的源代码并报告任何新信息。谢谢