2013-10-29 184 views
0

我想在C中创建一个可以获取环境变量的代码,然后使用strstr从该结果中搜索特定的单词。我使用的是UBUNTU OS和gcc编译器。这是我写的代码。评论是我预期会发生的事情。返回指针时的分段错误

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 

extern char **environ; 
extern char **tmp; 
extern char **tmp2; 

char *search_string(char *tmp,int x) 
{ 
     char string[]="ABC";   //I'm looking for ABC in the environment variable 
     char *pointer; 
     pointer=strstr(tmp,string); //pointer will point to the result of strstr 
     if(pointer != NULL) 
     {  printf("%s ,",tmp); 
       printf("data found : %s \n",pointer); 
     } else { 
       //hope to do something 
     } 
     return (pointer); 
} 

int main(char *tmp2) 
{ 
     int x = 0; 
     for(x=0;environ[x]!='\0';x++){ //I'm expecting it to keep looping until finish 
     tmp2=search_string(environ[x],x); //tmp2 will point to the function return value 
     printf("%s\n",tmp2);    //print the return value 
     } //If the search_string return NULL, does it consider string or something else? 
     return 0; 
} 

运行代码后,它因为核心转储而崩溃。这里是输出。

ABC=/tmp ,data found : ABC=/tmp 
ABC=/tmp 
Segmentation fault (core dumped) 

从我看到的,它只能做一次search_string。然后它崩溃。然后我用gdb的什么行它真正崩溃,找出和这里的结果:

Starting program: /home/fikrie/a.out 
ABC=/tmp ,data found : ABC=/tmp 
ABC=/tmp 

Program received signal SIGSEGV, Segmentation fault. 
__strlen_ia32() at ../sysdeps/i386/i686/multiarch/../../i586/strlen.S:99 
99 ../sysdeps/i386/i686/multiarch/../../i586/strlen.S: No such file or directory. 

我不从调试不解的是,它的接收,因为SEGV信号的误差。有人能指出我如何解决这个问题吗?是否因为search_string返回NULL值?

+0

'environ [x]'包含什么? 'main'中的参数列表是非标准的。 'environ指向char的指针 - 可能是问题出在那里。 – Sadique

+0

我很惊讶你可以遍历'environ [x]'直到找到NULL - 并且注意你应该真的测试NULL而不是'\ 0',因为这是一个指针... – Floris

+0

@Acme the environ [x]包含可以获取环境变量的指针。通过打印environ [x],我应该在/ etc/profile中获得environtment变量。 –

回答

2

问题是,如果search_string()找不到字符串,则返回NULL。然后您通过NULLprintf(),这会崩溃。

main(),你需要的东西,如:

if (tmp2) 
    printf("%s\n", tmp2); 

此外,tmp2变量的类型应该为char *,不char **的。并且没有理由不在main()上声明本地。

+0

是的,你完全正确。它的核心转储是因为search_string在第二次搜索后返回一个NULL,这是strstr的输出,如果它没有找到我指定的单词。因此,printf不能打印NULL结果。 –

+0

你的建议很好。它确实有效。当在代码中应用'if(tmp2)'时,它将在environ [x]中搜索一次。但在我的情况下,我想检查整个环境变量,这就是为什么我使用'for(x = 0; environ [x]!='\ 0'; x ++)'进行搜索。我只需要知道如何避免返回'NULL',如果'strstr'没有找到任何结果。我的方法错了吗? –

+0

@MohdFikrie:添加if(tmp2)* *表示它仍然在搜索整个环境 - 只是当目标字符串被找到时它才会执行'printf()'。为了看到这个,创建多个包含搜索字符串的环境变量(例如'ABCx = 1'' ABCy = 1')。 – caf

0

一个非常简单的改变你的主循环崩溃终止程序:

int main(char *tmp2) 
{ 
     int x = 0; 
     for(x=0;environ[x]!='\0';x++){ //I'm expecting it to keep looping until finish 
     tmp2=search_string(environ[x],x); //tmp2 will point to the function return value 
// >>>>> change these next two lines: 
     if(tmp2 != NULL) printf("%s\n",tmp2);    //print the return value 
     else printf("%s does not contain ABC\n", environ[x]); 
// <<<<< end of change 
     } //If the search_string return NULL, does it consider string or something else? 
     return 0; 
} 

请注意,如果你只希望一场比赛,你可以添加一个break;打印时将比分扳平。上面的代码打印出所有的环境变量 - 你可以看到它不停止...