簡體   English   中英

strcat上的段故障

[英]Seg fault on strcat

所以我的代碼出現段錯誤,而且我似乎無法弄清楚是什么原因造成的。 有誰能抓到我不是的東西?

從邏輯上講,我試圖通過將內容連接到末尾來創建char數組(字符串),然后將其添加到字符串數組中。

它最終應該看起來像是“ word1,word2,word3,word4,word5 ...等”

seg錯誤發生在strcat(str, ", ");

void save_ladder(graphNode *curNode) {

    char *str = malloc(1000 * sizeof(char));

    strcpy(str, "");
    strcat(str, curNode->word);
    strcat(str, ", ");

    graphNode *prev = curNode->prevWord;
    while (prev != NULL) {
            if (prev->prevWord != NULL) {
                strcat(str, prev->word);
                strcat(str, ", "); // SEG FAULT HAPPENS HERE
            }
            else 
                strcat(str, prev->word);

            prev = prev->prevWord;
    }

    ladders[numLadders++] = str;
}

gdb stacktrace:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004013d1 in save_ladder (curNode=0x6420f0) at wordladder.c:150
150             strcat(str, ", ");

有誰知道為什么會這樣?

可能是緩沖區溢出。 將以下代碼放在while循環中,然后檢查是否是這種情況:

printf ("%d %d\n", strlen (str), strlen (prev->word));

如果這兩個數字的總和接近1000,則您的緩沖區可能需要更大。

或者,如果第二個單詞似乎有點大或單詞太多,那么列表中的數據或列表結構本身都是可疑的。

此外,還有兩點。 第一個是您永遠不需要乘以sizeof(char)因為它始終為1(如果失敗,還應該檢查malloc的返回值)。

第二個是您可以簡化字符串構造,而無需在while內使用if語句:

strcpy(str, curNode->word);
graphNode *prev = curNode->prevWord;
while (prev != NULL) {
    strcat (str, ", ");
    strcat(str, prev->word);
    prev = prev->prevWord;
}

我有兩件事要注意/備注/回復:

  1. 您正在使用Painter的算法Schlemiel :在每個strcat() ,將再次遍歷到目前為止收集的字符串。 您應該考慮使用“光標指針”來指出您當前所在的位置:將每個strcat(str, ...)替換為strcpy(crsr, ...)然后crsr += strlen(crsr)crsr += strlen(crsr)以進行設置到字符串的末尾為止。 應在開始時將crsr設置為str

  2. 正如其他人所寫,您的代碼僅適合使用最多1000個字符。 您的構造函數已損壞,或者字符串之一太長。 無論如何,您的算法都過於靈活。 您應該考慮在附加之前檢查每個字符串的長度,如果不合適,請適當地重新分配str realloc() (不要忘了同時更新您的crsr 。)在這種情況下,您將不再有限制。

    在末尾將str大小調整為strlen(str) + 1 ,以免浪費內存。

我同意緩沖區溢出的答案。 我也同意代碼清理。 但是,我認為也許您應該研究asprintf或snprintf。 使用asprintf,您可以提供一個char **,它返回新字符串的位置。 如果您不需要自己仔細管理內存,這將非常有幫助。 該例程也是GNU擴展,因此請注意。 Snprintf讓您傳遞char *和剩余緩沖區的長度,以確定其余格式是否適合。 這將捕獲溢出。

這是使用asprintf的示例:

char *output = NULL;
char *last = NULL;

prev = curNode;
while (prev != NULL) {
    last = output;
    if (asprintf(&output, "%s,", prev->word) < 0) {
        break;  // error
    }
    if (last != NULL)
        free(last);
    }
    prev = prev->prevWord;
}

// remove trailing ',' here

注意:以上代碼未經測試(我正在平板電腦上編寫)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM