我编写了一个函数来测试给定路径是否是有效的Maildir目录(标准Maildir有三个子文件夹“cur”“new”和“tmp”)。函数接受假定的目录,检查这些子文件夹,并正确返回。
我在使用当前代码的第二个自由语句中得到了段错误,我同样得到了“无效的下一个大小”错误,组织略有不同。更令人困惑的是,它只是在一些目录上的段错误,而在其他目录上成功完成,没有明显的原因(尽管它将在哪些段落上是一致的)。随着第二个free()被注释掉,所有准确格式化的目录都成功完成。
显然我是双重解脱。我的问题是,为什么以及如何?如果第一个free在条件语句中并且我们在释放后立即返回,我们永远不会获得第二个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
}
答案 0 :(得分:5)
您有几个缓冲区溢出:strdup()
可能会分配一个char
数组,该数组足以容纳maildir
字符串,然后对strcat()
的调用将溢出数组。 (strcat()
,与strdup()
相反,不创建新的char
数组,因此必须确保自己确保数组你给它足够大以容纳结果字符串。)
顺便说一句,valgrind是您追踪内存管理错误的朋友。
答案 1 :(得分:1)
连接的重复字符串中没有足够的空间。
尝试:
char* new = (char*)calloc(strlen(maildir) + 5);
等
答案 2 :(得分:0)
我知道你得到了它,但就像小费一样......(对评论来说太大了)
检查strdup()
的{{1}}和NULL
这些指针的返回值。如果你没有内存会泄漏(它在你当前的代码中泄漏)。
strdup()函数应返回一个指向新字符串的指针,该字符串是s1指向的字符串的副本。 返回的指针可以传递给free()。如果无法创建新字符串,则返回空指针。