簡體   English   中英

C segfault在遞歸函數中調用strcat

[英]C segfault calling strcat in recursive function

我試圖在c中使用strcat連接字符串時遇到段錯誤。 gdb中的錯誤是:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1 (LWP 1)]
0xff1692b4 in strcat () from /lib/libc.so.1

相關代碼如下。 我在調用函數中對傳入的char * returnedString進行malloc,傳遞給returnedString的初始值只是“”。

char * printPostOrder(struct block * node, char * returnedString)
 {
 char * temp;
   temp = (char *)malloc(50 * sizeof(char));
  temp[0]='\0';
if(temp){
if (node != NULL)
{
    returnedString = printPostOrder(node -> left,returnedString);
    returnedString = printPostOrder(node -> right,returnedString);

    if (node -> left == NULL || node -> right == NULL)
    {
        if (node -> flag == 1)
        {
            sprintf(temp,"(%dA)\0",node -> size);
            strcat(returnedString,temp);
            free(temp);
        }
        else
        {
            sprintf(temp,"(%dF)\0",node -> size);
            //printf("%c",temp);
            strcat(returnedString,temp);

        }

    }
free(temp);
}
}

return returnedString;

}

真的很感激任何幫助!

首先,這兩行

char * temp;
temp = (char *)malloc(50 * sizeof(char));

應該用這一行代替

char temp[50];

否則,每次調用該函數時都會泄漏50個字節的內存。

其次,在頂層, returnedString應該被聲明為

static char returnedString[1000000];

因為你幾乎肯定是超越你的緩沖區strcat成。

作為解釋, strcat的文檔說:“字符串s1必須有足夠的空間來保存結果。” 注意, s1strcat的第一個參數,即輸出緩沖區。 strcat不會為你管理內存,也不會使輸出緩沖區更大。 如果輸出緩沖區不夠大,它就會崩潰。 因此,您需要確保以大輸出緩沖區開始。 你可以malloc那個緩沖區,或者像我上面所說的那樣靜態地聲明它,但你需要確保它足夠大以保存最終結果。

首先,你不是在任何地方調用free(temp)

最好的情況是,這只是占用了大量內存,但不會造成任何問題。

最糟糕的情況是(取決於您正在遍歷的樹的大小以及可用的內存量),實際上您的內存不足。 既然你沒有檢查malloc()是否返回NULL ,那么你會將一個NULL指針傳遞給sprintf() ,這很可能是你的段錯誤的原因。

假設你為“返回的字符串”分配了足夠的內存,我建議像這樣:

    char * printPostOrder(struct block * node, char * returnedString)
    {
            if (node != NULL)
            {
                    returnedString = printPostOrder(node -> left,returnedString);
                    returnedString = printPostOrder(node -> right,returnedString);

                    if (node -> left == NULL || node -> right == NULL)
                    {
                            if (node -> flag == 1)
                            {
                                    returnedString += sprintf(returnedString, "(%dA)",node -> size);
                            }
                            else
                            {
                                    returnedString += sprintf(returnedString, "(%dF)",node -> size);
                            }
                    }
            }
            return returnedString;
    }

snprintf返回寫入的字符數,因此這樣您就可以始終將此指針指向字符串的結尾。 每次你在那里寫,你有效地追加到原始字符串的末尾。 盡管如此,“假設您為返回的字符串分配了足夠的內存”非常重要。

關於strcat(str0,str1)的注釋:它不知道str0在哪里結束,因此每次調用它時,它都會遍歷str0中的字符以找到結尾。 只是更新一個指向字符串當前末尾的指針對我來說似乎比重新計算長度更好。

暫無
暫無

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

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