-5

當我在下一個代碼部分使用strtok時,我得到了分段錯誤核心轉儲。該代碼正在調試,但是當我運行它時,我得到了分段錯誤。我該如何解決它?爲什麼我得到分段錯誤核心轉儲?

struct{ char *name; 
void(*func)(void); 
}cmd[]={ 
{"read_cm",read_cm}, 
{"NA",NULL} 
}; 
int d; 
char *s="_\n"; 
    char *token2; 
    for(d=0;cmd[d].func!=NULL;d++) 
    { 
    token2=strtok((cmd[d].name),s); 
} 
+0

歡迎來到Stack Overflow!尋求調試幫助的問題(爲什麼這個代碼不工作?)必須包含所需的行爲,特定的問題或錯誤以及在問題本身中重現問題所需的最短代碼。沒有明確問題陳述的問題對其他讀者無益。請參閱:如何創建[mcve] ._ –

+0

當您創建[最小,完整和可驗證示例](http://stackoverflow.com/help/mcve)時,請確保它實際*編譯*。 –

+0

請正確格式化您的代碼。 –

回答

3

您不能修改字符串文字。任何修改字符串文字的嘗試都會導致未定義的行爲。

標準C函數strtok嘗試在將字符串拆分爲子字符串時插入終止零。

要解決該問題,請使用字符數組而不是指針name。或者動態分配內存並將一個字符串複製到指針name指向的分配內存中。

例如

struct 
{ 
    char name[8]; 
    void(*func)(void); 
} cmd[] = 
{ 
    { "read_cm", read_cm }, 
    { "NA", NULL } 
}; 

另一種方法是使用標準的C函數strcspnstrspn代替strtok找到的子串。

+1

你是怎麼知道這件事的? 'cmd [d] name'是一個語法錯誤,至多沒有試圖修改實際執行的文字。 :) –

+0

@SouravGhosh我認爲這只是一個錯字。 –

+0

'你可能不會'...好吧,你__必須不要,除非你確定在你的代碼中導致UB .. :) –