您不爲字符串分配足夠的空間。
你做了一個非正統的長度計算,忽略了'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()
序列)。謹防!
如果您的操作系統提供了'fstatat()',那麼你就需要構建路徑 - 你可以做'fstatat(dirfd(dirh),direntp-> d_name,&buf,0)' – caf 2010-07-04 07:01:03