malloc/free,似乎获得了多次释放
我编写了一个函数来测试给定路径是否是有效的 Maildir 目录(标准 Maildir 具有三个子文件夹 "cur" "new" 和 "tmp" )。函数接受假定的目录,检查这些子文件夹,然后正确返回。
我在当前代码的第二个自由语句中遇到了段错误,并且我同样遇到了“无效的下一个大小”错误,其组织略有不同。更令人困惑的是,它只在某些目录上出现段错误,而在其他目录上成功完成,没有明显的原因(尽管它在哪些目录上出现段错误是一致的)。注释掉第二个 free() 后,所有格式正确的目录都会成功完成。
显然我是双重释放的。我的问题是,为什么以及如何?如果第一个释放位于条件语句内,并且我们在释放后立即返回,则永远不会到达第二个释放。如果我们得到第二个免费的,这意味着我们跳过了第一个......对吧?
我意识到在这种情况下它完全没问题,因为系统将在程序结束时回收内存,但我对发生这种情况的原因更感兴趣,而不是仅仅让代码工作。如果我正在考虑不同的情况,函数由函数调用的函数等调用,并且内存可能是一个问题,该怎么办?我不需要第二个空闲来回收内存吗?
int is_valid_folder(char* maildir)
{
struct stat *buf;
buf = (struct stat *) malloc(sizeof(struct stat));
char* new = strdup(maildir);
char* cur = strdup(maildir);
char* tmp = strdup(maildir);
strcat (cur, "/cur"); strcat (new, "/new"); strcat (tmp, "/tmp");
if(stat(cur, buf) || stat(tmp, buf) || stat(new, buf))
{
printf("Problem stat-ing one of the cur/new/tmp folders\n");
printf("Error number %d\n", errno);
free(buf);
return 1;
}
free(buf);
return 0; //a valid folder path for this function
}
I've written a function to test if a given path is a valid Maildir directory (standard Maildir has the three subfolders "cur" "new" and "tmp" ). Function takes in the supposed directory, checks for those subfolders, and returns appropriately.
I'm getting a segfault at the second free statement with the current code, and I similarly got an "invalid next size" error with code of slightly different organization. Even more confusing, it only segfaults on some directories, while successfully completing on others, with no discernible reason (though it is consistent on which ones it will segfault on). With the second free() commented out, all accurately-formatted directories complete successfully.
Obviously I'm double-freeing. My question is, why and how? If the first free is inside the conditional statement and we return immediately after freeing, we never get to the second free. If we get to the second free, that means we skipped the first one... right?
I realize in this context it's perfectly fine because the system will reclaim the memory at the end of the program, but I'm more interested in the reason this is happening than in just making the code work. What if I were looking at a different situation, functions called by functions called by functions etc. and memory could possibly be a concern? Don't I need that 2nd free to reclaim memory?
int is_valid_folder(char* maildir)
{
struct stat *buf;
buf = (struct stat *) malloc(sizeof(struct stat));
char* new = strdup(maildir);
char* cur = strdup(maildir);
char* tmp = strdup(maildir);
strcat (cur, "/cur"); strcat (new, "/new"); strcat (tmp, "/tmp");
if(stat(cur, buf) || stat(tmp, buf) || stat(new, buf))
{
printf("Problem stat-ing one of the cur/new/tmp folders\n");
printf("Error number %d\n", errno);
free(buf);
return 1;
}
free(buf);
return 0; //a valid folder path for this function
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您有几个缓冲区溢出:
strdup()
可能会分配一个char
数组,该数组的大小刚好足以容纳maildir
字符串,并且调用strcat()
将导致数组溢出。 (strcat()
与strdup()
不同,不创建一个新的char
数组,因此您必须确保您提供的数组足够大以容纳生成的字符串。)顺便说一下,在跟踪内存管理方面,valgrind 是您的朋友错误。
You have several buffer overflows:
strdup()
probably allocates achar
array that is just large enough to hold themaildir
string, and the calls tostrcat()
will then overflow the arrays. (strcat()
, as opposed tostrdup()
, does not create a newchar
array, so you must ensure yourself that the array you give it is large enough to hold the resulting string.)By the way, valgrind is your friend when it comes to tracking down memory management bugs.
重复字符串中没有足够的空间用于串联。
尝试:
等等
There's not enough space in the duplicate strings for the concatenation.
try:
etc
我知道你明白了,但只是作为一个提示...(对于评论来说太大了)
检查
strdup()
的返回值是否为NULL
和free ()
当您使用完这些指针后。如果你不这样做,内存就会泄漏(它在你当前的代码中泄漏)。I know you got it, but just as a tip... (too big for a comment)
Check the return value of
strdup()
forNULL
andfree()
those pointers when you are done with them. If you don't memory will leak (it is leaking in your current code).