#include <stdio h>
#include <stdlib.h>
int main(int argc, char *argv[], char *envp[])
{
int i = 0;
while (envp[i] != NULL)
{
if (strstr(envp[i], "SHLVL") != NULL)
printf("%s\n", envp[i]);
i++;
}
setenv("SHLVL", "stackoverflow", 2);
i = 0;
while (envp[i] != NULL)
{
if (strstr(envp[i], "SHLVL") != NULL)
printf("%s\n", envp[i]);
i++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这段代码中SHLVL是一个现有的环境变量。当我尝试使用它更改该变量的值时,setenv它会给出预期的输出。
SHLVL=1
SHLVL=stackoverflow
Run Code Online (Sandbox Code Playgroud)
在另一种情况下:具有不存在的环境变量的相同代码
int main(int argc, char *argv[], char *envp[])
{
int i = 0;
while (envp[i] != NULL)
{
if (strstr(envp[i], "SHLVL") != NULL)
printf("%s\n", envp[i]);
i++;
}
setenv("arr", "33", 2); // non-exist environmental variable
setenv("SHLVL", "stackoverflow", 2);
i = 0;
while (envp[i] != NULL)
{
if (strstr(envp[i], "SHLVL") != NULL)
printf("%s\n", envp[i]);
i++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这里arr是一个不存在的环境变量。此代码给出的输出为
SHLVL=1
SHLVL=1
Run Code Online (Sandbox Code Playgroud)
我的问题是不存在的环境变量如何改变这里的输出?这里我使用gcc编译器。
参数envpinmain指向具有环境变量定义的原始数组。当您使用以下命令设置环境变量时setenv():
如果变量已经存在,则不会重新分配数组,只会更改变量的条目,因此枚举 指向的数组会envp给出预期的输出。
如果变量不存在,则需要扩展具有所有定义的数组,并且可能需要为此目的重新分配或移动,因此envp仍然指向原始数组的指针不具有存在于新数组,用于getenv()定位当前定义的数组。在这种情况下,使用枚举值envp将找不到新的变量定义,并且如果随后更改现有变量(如您的示例所示),则仅修改新数组,而指向的原始数组envp不会被修改,因此它仍然具有原始数组定义。这解释了您所观察到的情况,但不能保证这种行为,因为根据实现的不同,原始数组末尾可能有足够的空间用于新定义,因此不需要为每个新变量重新分配。
这种行为非常棘手,并且对定义字符串的内存管理产生深远的影响。传递envptomain不是标准的,并且仅在 unix 系统上可用,但即使在这些系统上,枚举环境定义的首选方法是使用environ由setenv()和更新的全局变量putenv():
extern char **environ;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |