2011-03-30 47 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"; 

在這種情況下,編譯器會創建一個數組放入堆棧,並將只讀字符串文字複製到其中。