2016-11-25 48 views
2
static void foo(unsigned char *cmd) 
    { 
     strcat(cmd, "\r\n"); 
     printf("\r\nfoo: #%s#", cmd); 

    } 
    int main() 
    { 
     foo("test"); 
     return 0; 
    } 

編譯器說分段錯誤(核心轉儲) 這裏的實際問題是什麼?在另一個函數中使用strcat:分段錯誤(核心轉儲)

+2

您正試圖將一些東西附加到字符串字面'「foo」的'不能修改。這是未定義的行爲。 –

+2

我認爲這不是你真正的代碼,它只是一個很好的MCVE。但是,也許在你的真實代碼中沒有涉及字符串文字。無論如何,除非你只需要調用一次,否則你應該避免使用'strcat()'。一旦你真的瞭解了在語言中是如何表示st刺以及它們真正**是什麼,那麼在c中建立字符串可以更有效地完成。 –

+1

在一對不相關的筆記上,打印時不需要使用回車。編譯器將確保換行符被轉換爲目標平臺的正確序列。另外,輸出到'stdout'(這是'printf'寫入的地方)默認是行緩衝的,所以輸出在新行上刷新,這使得換行符最無用。 –

回答

6

您有未定義的行爲。您不得修改字符串文字cmd指向字符串文字,strcat()嘗試連接到它,這是問題。

int main(void) 
    { 
     char arr[256] = "test"; 
     foo(arr); 
     return 0; 
    } 

您通常需要使用C中strcpy()strcat()等當作爲有,你可以緩衝區溢出的可能性要小心。 在我的示例中,我使用了256的數組,這對您的示例來說已經足夠了。但是如果你連接了大小不定的東西,你需要小心。

2

您正試圖向字符串文字test追加一些無法修改的內容。這是未定義的行爲。

你想這樣的:

static void foo(unsigned char *cmd) 
{ 
    strcat(cmd, "\r\n"); 
    printf("\r\nfoo: #%s#", cmd); 
} 

int main() 
{ 
    char test[50] = "test"; 
    foo(test); 
    printf("test after calling foo: %s\n", test); 
    return 0; 
} 
+0

絕對正確@michael walz – suren

2

在C字符串文字(如"test")是隻讀的字符數組。由於它們是隻讀的,因此它們不能被修改。由於它們是數組,它們具有固定的大小。你們都試圖修改字符串,並對其進行擴展。

1

其他人已經解釋了爲什麼你不能做到這一點。 您有兩種基本選擇:

  • 要麼你修改的地方字符串(與realloc()允許您添加後綴("\r\n"),但你必須要小心,並使用一個malloc分配的數據
  • 。否則,分配一個新的輸入大小的字符串,加上後綴的大小,並複製輸入字符串和前綴,然後返回它。在這種情況下,調用者需要返回字符串free()傳遞給函數的函數,但是這將會被處理)

編輯:如果您使用靜態分配的緩衝區,則可能必須向函數添加一個附加參數,指示可用緩衝區的大小。

+1

點1是錯誤的,你絕對不能'realloc'一個字符串常量。在下調之前修改您的答案。你只能「重新分配」以前由'malloc','calloc'和'realloc'分配的內存。 –

+0

@MichaelWalz:我想說的是:假設編譯器讓它發生,我不知道運行時的行爲。不管怎麼說,還是要謝謝你。 – Aif

+1

這是未定義的行爲。第一點仍然是誤導。 –

0

要與我的工作改變了計劃,如:

static void foo(unsigned char *cmd) 
{ 
    unsigned char local[10]; 
    strcpy(local, cmd); 
    strcat(local, "\r\n"); 
    printf("\r\nfoo: #%s#", local); 

} 
int main() 
{ 
    foo("test"); 
    return 0; 
}