c - UNIX 上使用 free() 时 putenv() 的问题

标签 c unix memory-management free

我试图通过在此之前连接 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 将不会添加该值。

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

有任何想法吗?

最佳答案

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

这在 putenv() 的 OpenGroup 描述中以相当模糊的方式指出:

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

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

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

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

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

关于c - UNIX 上使用 free() 时 putenv() 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3674089/

相关文章:

c - 如何在 Rust 中获取给定 CPU 寄存器的偏移量

c++ - 每次我使用 placement new 分配时都会隐式调用析构函数

ios - 验证对象释放

c - 我在使用 sscanf 函数时犯了错误吗?

c - 位填充 (C)

Objective-C : "Hello world"已编译!没有基础标题。为什么?

c++ - Cyassl-2.4.2 缺少 libcyassl.a 文件

c++ - unistd.h read() 正在读取更多数据然后被写入

linux - 比较文件系统空间使用情况随时间的变化

空 PHP 脚本上的 PHP memory_get_usage()