我有以下代码。它给了我一个空闲内存的问题,但我还没弄清楚究竟是什么问题。似乎getpwuid(buf->st_uid);
与readdir(dirh);
或与stat函数不相符。有谁知道为什么?
buf = (struct stat*) malloc(sizeof(struct stat));
for (dirp[i] = readdir(dirh); dirp[i] != NULL; dirp[++i] = readdir(dirh)){
ptr=(char *)malloc(sizeof(strlen(mydir)));
ptr=strdup(mydir);
strcat(ptr,dirp[i]->d_name);
stat(ptr,buf);
//modos();
getpwuid(buf->st_uid);
printf("\t%s\n",ptr);
//we free the buf memory
}
free(buf);
closedir(dirh);
答案 0 :(得分:4)
ptr=(char *)malloc(sizeof(strlen(mydir)));
ptr=strdup(mydir);
最多看起来有问题: - )
你在第一个内存中分配一些内存,然后在第二个分配更多内存时将其泄漏。
即使这不是问题,我也从未见过范式:
sizeof(strlen(mydir))
调用sizeof
时,您可能会使用strlen()+1
或malloc
。我认为你拥有的东西,即使它有效,也会为size_t
分配足够的空间,strlen
的返回值。我可能错了,但我不认为这是有意义的,因为你因为泄漏而没有使用那个记忆。
还有其他问题,例如:
getpwuid
应该返回您忽略的struct passwd *
。strdup
为您提供了一个完全正确大小的字符串的副本,然后您strcat
就可以了,几乎肯定会破坏内存。现在这是未经测试的,但我认为这可能是一个更好的起点:
struct stat buf;
struct dirent * direntp;
struct passwd * pwdp
for (direntp = readdir(dirh); direntp != NULL; direntp = readdir(dirh)) {
// Allocate enough space for directory, separator, file and nul character.
ptr = (char*)malloc (strlen(mydir) + 1 + strlen (direntp->d_name) + 1);
strcpy (ptr, mydir);
strcat (ptr,"/");
strcat (ptr, direntp->d_name);
stat(ptr, &buf);
//modos();
pwdp = getpwuid (buf.st_uid);
printf("\t%s\n",ptr); // prob. need something from pwdp printed here as well.
// Don't leak.
free (ptr);
}
closedir(dirh);
答案 1 :(得分:3)
您没有为字符串分配足够的空间。
你做一个非正统的长度计算,忽略'mydir'的实际长度;然后你做一个目录名的好副本(但泄漏以前分配的内存);然后在strdup()
分配的空间末尾连接名称,这总是很糟糕。如果省略了sizeof()
,那么你将为一个空终止目录字符串分配一个字节太少。
您也不应该缓存来自readdir()
的单独返回值,因为它通常每次都返回指向同一位内存的指针。你肯定没有权利假设它不这样做。
如果你真的在循环中释放buf,你也会践踏释放的内存;你只分配一次,并且多次免费。
通常,您根本不需要分配buf
;它不是那么大的结构。
你也不会在目录名和文件名组件之间有一个斜杠分隔符;如果你确保mydir
最后有一个可能无关紧要。
这是一个简单的程序,或多或少地做了必要的事情。
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
static const char mydir[] = "./";
DIR *dirh;
size_t dlen = strlen(mydir) + 1;
if ((dirh = opendir(mydir)) != 0)
{
struct dirent *dirp;
while ((dirp = readdir(dirh)) != 0)
{
char *str = malloc(dlen + strlen(dirp->d_name));
if (str != 0)
{
struct stat buf;
strcpy(str, mydir);
strcat(str, dirp->d_name);
if (stat(str, &buf) == 0)
{
struct passwd *pwd = getpwuid(buf.st_uid);
if (pwd != 0)
printf("\t%s (%s)\n", str, pwd->pw_name);
}
free(str);
}
}
closedir(dirh);
}
return 0;
}
注意: dlen
的计算是正确的,但仅仅因为mydir
的值包含尾部斜杠。如果目录名称不包含该尾部斜杠,则代码将需要更改长度计算并格式化复合名称(strcpy()
strcat()
序列)。小心!