【问题标题】:struct passwd is source of memory leak - how to properly free?struct passwd 是内存泄漏的来源 - 如何正确释放?
【发布时间】:2016-10-24 19:43:53
【问题描述】:

使用“struct passwd”隔离了 5 块内存泄漏。尝试了几个不同的免费(用户)电话无济于事。这个结构是如何被释放的?关于该主题的几个不同的 SO 问题,但我发现很少有关于如何处理这个特定结构的文档。否则程序可以正常工作。谢谢。

#include <assert.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
    pid_t pid = getpid();
    uid_t uid = getuid();
    struct passwd *user = getpwuid(uid);
    unsigned int bufferMaxLen = strlen(".dir.") + strlen(user->pw_name) + 10;
    char* dirName = malloc(bufferMaxLen * sizeof(char));
    assert(dirName != NULL);
    sprintf(dirName, "%s.dir.%d", user->pw_name, pid);

    printf("bufferMaxLen is: %d\n", bufferMaxLen);
    printf("Directory name is: %s\n", dirName);

    free(dirName);
    return 0;
}

【问题讨论】:

  • 你怎么知道它在泄漏内存? man getpwuid 明确声明“返回值可能指向静态区域,并且可能被后续调用 getpwent(3)、getpwnam() 或 getpwuid() 覆盖。(不要将返回的指针传递给免费(3)。)
  • 我相信getpwuid 的确切工作方式是特定于平台的。
  • valgrind
  • 哦,即使忽略警告也无法释放所有内存的原因当然是该函数分配了一个内部缓冲区来读取 /etc/password (大概是与身份服务交互)。
  • @LHMathies - 哈哈,我只是在做一个类似的项目,但又遇到了同样的问题 - 你是通灵者!

标签: c struct memory-leaks


【解决方案1】:

您可以通过提供自己的struct password 和用于读取/etc/passwdgetpwuid_r 的缓冲区来控制内存分配。

(这也有助于重入,这就是函数具有_r 后缀的原因——未添加后缀的版本“允许”分配单个全局缓冲区)。

【讨论】:

    【解决方案2】:

    使用该代码,它看起来像是实现特定的库功能。当您第一次调用函数时,库分配内存并且从不释放它是很正常的:在正常执行期间没有办法或机会释放它,并且在退出处理程序中释放单个内存分配是完全没有意义的,当它们大约被程序退出后立即释放。

    您可以将这种分配视为静态数据,但它们只是指向缓冲区/结构的静态指针,仅在需要时分配。好处是,如果从不调用相关函数,则使用更少的内存。缺点是如果函数确实被调用,代码、运行时成本和内存使用会稍微复杂一些,更不用说内存分析器的混乱了,你的问题证明了:-)。

    像 Valgrind 这样的工具有忽略过滤器来隐藏这种“泄漏”。

    【讨论】:

    • 这是一个很好的点,这个泄漏是“正常​​的”,你应该设置 Valgrind 来忽略它,除非你这样做是为了证明你可以:)
    • 有趣!没有这样的动机,只是在检查泄漏的实践中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    相关资源
    最近更新 更多