問題代碼如下:
#include <unistd.h>
#include <string.h>
#include <stdio.h>
void parse(char* buf,char* args[])
{
printf("buf=%s\n",buf);
int i=0;
while(*buf!='\0')
{
args[i]=buf;
while((*buf!=' ')&&(*buf!='\t')&&(*buf!='\n')) buf++;
while( (*buf==' ') || (*buf=='\t') || (*buf=='\n') )
{
*buf = '\0'; //注意本行
buf++;
}
i++;
}
args[i]='\0';
int j=0;
while(j<i)
{
printf("arg[%d]=%s\n",j,args[j]);
j++;
}
return;
}
int main()
{
char* args[4];
char buf[100]="a b c"; //-1-這裡字符數組的定義有講究
parse(buf,args);
execvp(*args,args);
return 0;
}
-1-處的字符數組定義時需要注意,按照上面代碼的代碼定義並初始化沒有問題,此時buf地址分配在非常量區,即非只讀區,所以可以調用parse(buf,args)中的*buf='\0';
使用gdb查看此時堆棧結構:
Breakpoint 1, parse (buf=0x7fffffffe661 " b c", args=0x7fffffffe640) at parse.C:15
15 *buf = '\0';
但是如果此時這樣定義:
char* buf="a b c";
此時的buf分配在常量區,調用parse(buf,args)中的*buf='\0'時就會出現“Segmentation fault”,此時使用gdb查看出現錯誤的原因是:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400629 in parse (buf=0x4007f3 " b c", args=0x7fffffffe640) at parse.C:15
15 *buf = '\0';
此時可以看到兩次分配的buf的地址區域是不一樣的,正確地址分配在非常量區(應該是在棧區),錯誤時分配在常量區;