2012-05-27 14 views
2

我编写了一个简单的函数,用于在Linux中为函数execvp创建一个C字符串(NOT C++)。在C中编写向量的字符串,程序接收到的信号SIGSEGV,分割错误

这是我的代码:

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

char** vecting(char *cstring) { 

    int w_count = 0;   //word count 
    char *flag = cstring; 

    while (*flag != '\0') { 
     if (*flag == ' ' || *flag == '\n' || *flag == '\t') 
      *flag = '\0'; 
      flag++; 
     else { 
      w_count++; 
      while (*flag != ' ' && *flag != '\n' && *flag != '\t' && *flag != '\0') 
       flag++; 
     } 
    } 

    char **cvector = (char **)malloc(sizeof(char *)*(w_count+1)); 
    cvector[w_count] = NULL; 
    int v_count;    //vector count 

    for (v_count = 0, flag = cstring; v_count < w_count; v_count++) { 
     while (*flag == '\0') 
      flag++; 
     cvector[v_count] = flag; 
     while (*flag != '\0') 
      flag++; 
    } 
    return cvector; 
} 

int main() 
{ 
    char *p = "This is a BUG"; 
    char **argv = vecting(p); 
    char **temp; 

    for (temp = argv; *temp != NULL; temp++) 
     printf("%s\n", *temp); 
    return 0; 
} 

当我运行它,我it'get Segmentation fault

然后我调试它,我才发现,当运行

*flag = '\0'; //(in line 12)

计划接收信号SIGSEGV,分割过错。

当时*flag = ' '

我不能unstand为什么程序接收到的信号SIGSEGV当程序改变cstring

回答

6
char *p = "This is a BUG"; 

是一个字符串文字,它的未定义行为对其进行修改。​​意味着flag指向p指向相同的位置(这恰好是只读内存)。你试图做的(现在是这样)是非法的。

尝试

char p[] = "This is a BUG"; 
+0

过去,可以修改,因为文字字符串在内存中没有标记为只读。现在编译器将存储文字字符串的内存标记为只读,所以无论您尝试修改它,您都将获得SEGFAULT。 – nhahtdh

+0

@nhahtdh真的吗?你有参考吗?该标准说这是未定义的行为,我倾向于更加信任它。 –

+0

@nhahtdh此外,未定义的行为意味着任何事情都可能发生。它不需要崩溃。你以前的意思是什么?你的意思是十年前?因为C++ 03和C++ 11都声称这是UB。不知道以前的版本,但这应该够了。 –

1

得到SIGSEGV的原因是"This is the bug"串放入常量部分。程序加载时相应的内存区域标记为只读。当程序试图写入只读存储区时,它会收到分段错误。

相关问题