返回指针时出现分段错误
Posted
技术标签:
【中文标题】返回指针时出现分段错误【英文标题】:Segmentation fault when returning a pointer 【发布时间】:2013-10-29 02:55:56 【问题描述】:我正在尝试用 C 语言编写一个可以获取环境变量的代码,然后使用 strstr 从该结果中搜索特定的单词。我正在使用 UBUNTU 操作系统和 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)
据我所知,它只能执行 1 次 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 值?
【问题讨论】:
environ[x]
包含什么? main
中的参数列表是非标准的。 environ
s 指向 char 的指针-也许问题就在那里。
我很惊讶你可以循环 environ[x]
直到你找到一个 NULL - 请注意你应该真正测试 NULL 而不是 '\0' 因为这是一个指针......
@Acme environ[x] 包含可以获取环境变量的指针。通过打印 environ[x],我应该在 /etc/profile 中获得环境变量。
@Floris 我可以循环,因为据我所知,它是一个指针数组,将在收集所有数据后结束。据我所知,数组将以'/0'结尾对吗?
一个 string 将以 '\0'
结尾,但是没有理由为什么 pointers 数组的最后一个元素应该包含 NULL
.尽管这样做是件好事——这意味着您不必显式传递数组的大小。但我不知道 C 标准的任何部分说它应该是这样。
【参考方案1】:
问题是如果search_string()
没有找到字符串,它会返回NULL
。然后将 NULL
传递给 printf()
,这会崩溃。
在main()
中,您需要类似:
if (tmp2)
printf("%s\n", tmp2);
另外,tmp2
变量的类型应该是 char *
,而不是 char **
。并且没有理由不将其声明为 main()
本地。
【讨论】:
是的!你是完全正确的。它核心转储,因为 search_string 在第二次搜索后返回 NULL,如果它没有找到我指定的单词,这是 strstr 的输出。因此,printf 无法打印 NULL 结果。 你的建议很好。它确实有效。在代码中应用 'if(tmp2)' 时,它将在 environ[x] 中搜索 1 次。但就我而言,我想检查整个环境变量,这就是我使用 'for(x=0;environ[x]!='\0';x++)' 进行搜索的原因。如果“strstr”没有找到任何结果,我只需要知道如何避免返回“NULL”。我的方法错了吗? @MohdFikrie:添加if (tmp2)
确实意味着它仍在搜索整个环境-只是它只会在找到目标字符串时执行printf()
.要查看这一点,请创建多个包含搜索字符串的环境变量(例如 ABCx=1
ABCy=1
)。
我已经尝试过您的建议,但它的行为不正常。我添加了“ABC=/home”、“ABCx=/etc”和“ABCy=/home/fikrie”。通过使用命令'env'。我发现'ABC = / home'在顶部,其他2在底部。当我运行代码时,它只找到'ABC / home'而不是其他2。我假设它会停止搜索如果它在环境中找到'NULL',即使它的下部仍然有'ABC' .听起来对吗?
@MohdFikrie:它不会停止搜索,因为您的代码表示无论是否找到匹配项,都将继续搜索,直到到达环境结束。您可能没有导出额外的环境变量。【参考方案2】:
对主循环的一个非常简单的更改可以防止程序崩溃:
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;
。上面的代码打印出所有的环境变量——你可以看到它并没有停止...
【讨论】:
以上是关于返回指针时出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章