以下代码似乎以“分段错误(核心转储)”结束。我认为environ变量应该以NULL终止指针结束。我只想打印每个环境变量,所以我做错了什么?我怎么知道我已经到了最后一个环境变量?
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
int main(int argc, char *argv[])
{
int i;
char *s = *environ;
for(i=0; s!=NULL; i++)
{
printf("env%d: %s\n", i, s);
s = *(environ+( sizeof(char *)*i ));
}
return 0;
}
答案 0 :(得分:5)
您使用
*(environ+( sizeof(char *)*i ))
完全错了。指针算术不正确。乘以sizeof(char *)
是错误的。这导致在阵列上迈出大步并且跑到最后。如果你想使用指针运算,你只需写:
*(environ+i)
但是,当然,在那一点上,你已经把它简化为一种相当笨重的方式来说:
environ[i]
因此,在我看来,你应该最清楚地使用environ[i]
来编写循环。例如:
int i = 0;
while(environ[i] != NULL)
{
printf("env%d: %s\n", i, environ[i]);
i++;
}
或者作为for循环:
for(int i = 0; environ[i] != NULL; i++)
{
printf("env%d: %s\n", i, environ[i]);
}
答案 1 :(得分:3)
#include <unistd.h>
#include <stdio.h>
extern char **environ;
//...
int i = 0;
while(environ[i]) {
printf("%s\n", environ[i++]);
}
不要忘记c有指针算术,所以environ+( sizeof(char *)*i )
必须是environ + i
编译器自动将基地址移动i * sizeof(char *)。
答案 2 :(得分:3)
现在,您正在取消引用第一个指针(获取第一个环境变量)。将迭代指针更改为指向指针的指针。按照目前的情况,您将双重打印第一个条目。
此外,指针的增量是导致分段错误的原因。它的步幅不止一个指针宽度,导致你大部分时间都在数组的末尾运行,同时也缺少大多数条目。
char ** s = environ;
for( int i = 0; *s != NULL; i++ )
{
printf( "env%d: %s\n", i, * s );
s ++;
}
答案 3 :(得分:3)
使用指针算法是一种方法,只需确保正确递增:
size_t i = 0; /* To index arrays (or just count them) or to access memory, size_t is the
preferred type, as it is guaranteed to be wide enough to access all
memory. Also it does not waste any bit for unused negative numbers. */
char ** s = environ;
for(; *s != NULL; ++i)
{
printf("env%zu: '%s'\n", i, *s);
++s; /* Incrementing a pointer increments so many bytes
as the type the pointer is pointing to uses. */
}
但我使用了while
- 循环:
char ** s = environ;
while (*s)
{
printf("env%td: '%s'\n", (*s - *enviro), *s);
++s;
}