2011-03-30 43 views
-1

当我编译并运行我的代码时,它在打印“开始”后立即出现总线错误。 这里是发生了什么:来自printf的不合逻辑的总线错误C

的bash-3.2 $ ./remDup
开始
总线错误

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

void removeDups(char* str) 
{ 
    int len = strlen(str); 
    int i = 0; 

    for (i = 0; i < len; i++) { 
     char a = str[i]; 
     int k = i + 1; 
     int c = 0; 
     int j = 0; 

     for (j = k; j < len; j++) { 
      if (a != str[j]) { 
       str[k] = str[j]; 
       k++; 
      } else c++; 
     } 

     len -= c; 
    } 

    str[len] = '\0'; 
} 

int main(int argc, const char* argv[]) 
{ 
    char *str1 = "apple"; 

    printf("%s -> ", str1); 
    removeDups(str1); 
    printf("%s\n ", str1); 

    return 1; 
} 

回答

4

如果您定义为一个字符串:

char *str1 = "apple"; 

你是不允许修改的内容 - 的标准是很清楚,这是不确定的行为(一)。使用:

char str1[] = "apple"; 

取而代之,它会给你一个可修改的副本。它的功能上等同于:

char str1[6]; strcpy (str1, "apple"); 

的(a) C99 6.4.5 "String literals"6状态:

这些阵列是否是不同的条件是它们的元件具有相应的值是不确定的。如果程序试图修改这样一个数组,那么行为是不确定的。

+0

哇谢谢。 :)但为什么我会在调用removeDups之前得到总线错误? – gfrkwiz 2011-03-30 08:49:31

+2

你不这样做,崩溃在'removeDups' - 你没有看到你的''%s - >''printf输出,因为它没有'\ n' - 所以它没有得到事故发生前冲出。 – GrahamS 2011-03-30 08:53:37

4

你修改字符串常量,其通常驻留在只读存储器中。该标准还规定,试图修改文字是未定义的行为。

当你使用指针到字符串常量,您应该将它们声明为const,const char * str="text";或阵列char str[] = "text";

更改为如:

char str1[] = "apple"; 

在这种情况下,编译器会创建一个数组放入堆栈,并将只读字符串文字复制到其中。