【问题标题】:Issue with putenv() on UNIX when using free()在 UNIX 上使用 free() 时出现 putenv() 问题
【发布时间】:2011-04-10 02:24:22
【问题描述】:

我试图通过在此之前连接 str1 和 str2 在 UNIX 上使用 putenv()。 我想在环境中添加一个变量,或者修改一个变量,所以我正在调用 putenv()(或者我可以同样调用 setenv())。

基本上,我接收str1和str2,我创建str1=str2并将它作为参数传递给putenv()。

我展示的代码有效,但是当我取消注释 free() 调用时,它不会:不会为环境添加/修改变量。

size_t size = strlen(str1) + strlen(str2) + 2; // 2 is for the '\0' and the '='
char *tmp = (char *) malloc(sizeof(char) * size);
char *p;
int pos = 0;

// Copy first word
p = str1;
while (*p != NULL) {
    tmp[pos++] = *p++;
}

// Add the '='
tmp[pos++] = '=';

// Copy second word
p = str2;
while (*p != NULL) {
    tmp[pos++] = *p++;
} 

// Add null character
tmp[pos] = '\0';

int ret = putenv(tmp);
if (ret != 0) {
    perror("putenv failed");
}

//free(tmp); // This line is the problem when not commented

我为代码冗余道歉,我知道这两个 while 循环是相同的。我遇到的问题是,如果我取消注释 free 语句,然后调用“env”来打印环境,putenv 将不会添加值。

我不知道为什么会这样。现在让它工作,我有一个我不喜欢的内存泄漏。当我使用数组而不是指针时,它会产生与取消注释免费相同的问题。

有什么想法吗?

【问题讨论】:

    标签: c unix memory-management free


    【解决方案1】:

    putenv() 要求设置到环境中的字符串存在,因为它不复制字符串;它使用指向为参数提供的字符串的指针。

    OpenGroup 对 putenv() 的描述中以相当模糊的方式指出了这一点:

    http://www.opengroup.org/onlinepubs/009695399/functions/putenv.html

    “一个潜在的错误是使用自动变量作为参数调用 putenv(),然后在字符串仍然是环境的一部分时从调用函数返回。”

    您的问题有两种可能的解决方案:

    1 - 要使用 putenv() 获得所需的内容,您可以使用静态字符串,或者使用在不需要环境变量之前不会超出范围的字符串。

    2 - 或者,使用 setenv(const char *envname, const char *envval, int overwrite),它比 putenv 更容易使用,分配内存并复制字符串,并且不需要像你一样连接字符串现在正在做。

    【讨论】:

    • 正确 - 如果您随后更改环境变量的值,您必须放弃内存,并容忍泄漏。基本上,如果您有 setenv() 可用,请不要使用 putenv()。现在是否有带有putenv() 和没有setenv() 的系统是有争议的; 10 年前,使用 setenv() 更多的是一种可移植性的责任 - 而 putenv() 是可靠的,但在不泄漏的情况下使用起来很麻烦。
    • 非常感谢您的帮助!我将切换到 setenv(),非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2021-03-26
    相关资源
    最近更新 更多