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

时间:2010-09-09 05:47:05

标签: c unix memory-management free

我试图在UNIX之前通过连接str1和str2来使用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将不会添加该值。

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

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

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

这在putenv()的OpenGroup描述中以一种相当模糊的方式注明:

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

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

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

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

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