environ
是一个指针,这意味着它sizeof(environ)
不是该数组中的项目数。相反,它是指针的大小,在您的情况下可能是四或八。
如果environ
是与(最后一个是空指针的字符指针数组)相同的结构argv
,则需要通过遍历数组来确定其大小,直到找到 NULL。
类似的东西(未经测试,但这个想法是合理的):
char **envPtr = environ;
int size_list = 0; // probably should be size_t
while (*envPtr != NULL) {
envPtr++;
size_list++;
}
您可以在这个完整的程序中看到效果(进行了一些更改以绕过其他一些错误):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define full_string "xyzzy=plugh"
#define len_string strlen(full_string)
int main (int argc, char **argv) {
int k, size_list = sizeof(environ);
char **tmp_ptr = malloc ((size_list + 1) * sizeof ( char*));
for (k = 0; k < size_list; ++k) printf ("[%s]\n", environ[k]);
for (k = 0; k < size_list; ++k) tmp_ptr[k] = environ[k];
tmp_ptr[size_list] = NULL;
environ = tmp_ptr;
environ[size_list] = malloc (len_string + 1);
strcpy(environ[size_list],full_string);
printf ("=====\n");
for (k = 0; k <= size_list; ++k) printf ("[%s]\n", environ[k]);
return 0;
}
这仅输出我的四个环境变量,因为我有四字节指针:
[ORBIT_SOCKETDIR=/tmp/orbit-pax]
[SSH_AGENT_PID=1978]
[GPG_AGENT_INFO=/tmp/seahorse-tNDhG9/S.gpg-agent:2005:1]
[TERM=xterm]
=====
[ORBIT_SOCKETDIR=/tmp/orbit-pax]
[SSH_AGENT_PID=1978]
[GPG_AGENT_INFO=/tmp/seahorse-tNDhG9/S.gpg-agent:2005:1]
[TERM=xterm]
[xyzzy=plugh]
更改代码以正确确定环境的大小:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define full_string "xyzzy=plugh"
#define len_string strlen(full_string)
int main(int argc, char **argv) {
int k, size_list = 0;
char **envPtr = environ;
while (*envPtr != NULL) {
envPtr++;
size_list++;
}
char **tmp_ptr = malloc ((size_list + 1) * sizeof (char*));
for (k = 0; k < size_list; ++k) printf ("[%s]\n", environ[k]);
for (k = 0; k < size_list; ++k) tmp_ptr[k] = environ[k];
tmp_ptr[size_list] = NULL;
environ = tmp_ptr;
environ[size_list] = malloc (len_string + 1);
strcpy(environ[size_list],full_string);
printf ("=====\n");
for (k = 0; k <= size_list; ++k) printf ("[%s]\n", environ[k]);
return 0;
}
给了我很多:
[ORBIT_SOCKETDIR=/tmp/orbit-pax]
[SSH_AGENT_PID=1978]
[GPG_AGENT_INFO=/tmp/seahorse-tNDhG9/S.gpg-agent:2005:1]
[TERM=xterm]
[SHELL=/bin/bash]
[GTK_RC_FILES=/etc/gtk/gtkrc:/home/pax/.gtkrc-1.2-gnome2]
[WINDOWID=62914564]
[GNOME_KEYRING_CONTROL=/tmp/keyring-RADe9n]
[GTK_MODULES=canberra-gtk-module]
[USER=pax]
:
[XAUTHORITY=/var/run/gdm3/auth-for-pax-AO1dYc/database]
[_=./testprog]
=====
[ORBIT_SOCKETDIR=/tmp/orbit-pax]
[SSH_AGENT_PID=1978]
[GPG_AGENT_INFO=/tmp/seahorse-tNDhG9/S.gpg-agent:2005:1]
[TERM=xterm]
[SHELL=/bin/bash]
[GTK_RC_FILES=/etc/gtk/gtkrc:/home/pax/.gtkrc-1.2-gnome2]
[WINDOWID=62914564]
[GNOME_KEYRING_CONTROL=/tmp/keyring-RADe9n]
[GTK_MODULES=canberra-gtk-module]
[USER=pax]
:
[XAUTHORITY=/var/run/gdm3/auth-for-pax-AO1dYc/database]
[_=./testprog]
[xyzzy=plugh]
对于它的价值,您的代码存在以下问题:
- 显然,环境大小的计算不正确。
- 从 - 转换返回值
malloc
- 这在 C 中是不明智的,因为它可能会导致代码问题对您隐藏。
- 不将新列表的最后一个元素设置为 NULL。
- 不检查内存不足的情况。
除了最后一个之外,所有这些都固定在我上面的最终代码示例中。