environ似乎没有以NULL结尾

时间:2014-10-13 16:17:12

标签: c null segmentation-fault environment-variables

以下代码似乎以“分段错误(核心转储)”结束。我认为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;
}

4 个答案:

答案 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; 
}
相关问题