c - 我如何修复由 c 中的 man 2 stat 成员造成的泄漏

标签 c macos unix malloc free

我正在重新实现 unix ls 命令,但是当我测试泄漏时,它显示:进程 44151:248 个节点分配为 45 KB,进程 44151:28 个泄漏,总共 560 个泄漏字节。所以我尝试释放 pwd 和 grp。但它说我正在释放从未分配的内存。

static int      one(const struct dirent *unused)
{
    (void)unused;
    return (1);
}

void            ls_l(void)
{
    struct stat     statbuf;
    struct group    *grp;
    struct passwd   *pwd;
    struct dirent   **sd;
    int             n;
    int             i;

    pwd = getpwuid((geteuid()));
    n = scandir(".", &sd, one, alphasort);
    i = 1;
    while (i < n)
    {
        while (strncmp(sd[i]->d_name, ".", 1) == 0)
            i++;
        if (stat(sd[i]->d_name, &statbuf) == 0)
        {
            ft_perm(sd[i]->d_name);
            ft_printf(" %-2d %4s  ", statbuf.st_nlink, pwd->pw_name);
            if ((grp = getgrgid(statbuf.st_gid)) != NULL)
                ft_printf(" %-8.8s %5d %s %s\n",grp->gr_name,
                        (int)statbuf.st_size,ft_group(ctime(&statbuf.st_mtime)),
                        sd[i]->d_name);
            else
                ft_printf(" %-8d %5d %s %s\n", statbuf.st_gid,
                        (int)statbuf.st_size,ft_group(ctime(&statbuf.st_mtime)),
                        sd[i]->d_name);
        }
        free(sd[i]);
        i++;
    }
    free(sd);
}

最佳答案

while (strncmp(sd[i]->d_name, ".", 1) == 0)
            i++;
// code
free(sd[i]);

这就是内存泄漏的原因。您永远不会释放文件名以句点开头的 sd 元素。

此外,我会使用 sd[i]->d_name[0] == '.' 进行比较。 strncmp() 对此来说太过分了。循环的固定版本:

for (int i = 0; i < n; i += 1) {
   while (i < n && sd[i]->d_name[0] == '.') {
       free(sd[i++]);
   }
   if (i == n) {
      break;
   }

    // code

    free(sd[i]);
}
free(sd);

此外,这还可以处理每个返回的文件都是点文件的情况,在这种情况下,您的原始文件将导致读取超过sd数组的末尾。

关于c - 我如何修复由 c 中的 man 2 stat 成员造成的泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52081734/

相关文章:

c - 为什么++*p++有效而++i++无效?

c - 我需要 C 程序方面的帮助

c - 如何同时使用 scanf 和 fgets 读取文件

python - 凌乱的 Python 安装? (OS X)

linux - 如何删除 brew 和 apt-get 之间的重复包

c - execv 不适用于 "execv("/bin/echo", ["echo","$PATH"] )?

c - 将整数和字符数组写入文件

ios - 将 www 文件夹重新添加到 xcode phonegap 项目

java - 为 Mac 用户制作 Java 应用程序

ruby - Ubuntu 在启动时启动 Rails