簡體   English   中英

長字符串中的分段錯誤

[英]Segmentation fault in a long string

我正在編寫一個打印為標准輸出的函數,就像常規 printf 函數所做的那樣,但在采用 %d 或 %s 等指標時,它需要 {i} 或 {s}。 我遇到的問題是,當格式參數的字符串太長約 23 個字符時,我在調用 vfprintf 函數的行出現分段錯誤。

        int mr_asprintf(const char *format, ...)
        {
            int i;
            char *newFormat = calloc(1,sizeof(char));
            char integer[3] = "%d";
            char str[3] = "%s";
            char tmpStr[2];
            va_list args;
            newFormat[0] ='\0';
            tmpStr[1] = '\0';
            for(i=0;format[i]!='\0';i++) // convert to printf syntaxe
            {
                if(format[i]=='{' && format[i+2]=='}') //check if it's {x}
                {
                    switch(format[i+1]) 
                    {
                        case 'i':
                            strcat(newFormat,integer);
                            i += 2;
                            break;
                        case 's':
                            strcat(newFormat,str);
                            i += 2;
                            break;
                    }
                }
                else
                {
                    tmpStr[0] = format[i];
                    strcat(newFormat,tmpStr);
                }

            }
            va_start(args,format);
            int s = vfprintf(stdout,newFormat,args);
            va_end(args);
            free(newFormat);
            return s;
        }

測試示例:

    int main()
    {

        char *result = mr_asprintf("bce }edadacba{i}}aa}da{s}fe aeaee d{i}cefaa",55,"XXX",66);
        printf("%s\n",result);
        return 0;
    }

你的字符串newFormat被分配為大小 1,你用 strcat 附加到它 - 但 strcat 不做任何數組大小調整,所以newFormat很快就會開始在未分配的內存上踩踏。 您的輸出字符串的長度將始終 <= 輸入字符串的長度,因此您可能應該分配一個該大小的字符串。

最后,雖然這不應該在 vprintf 中導致段錯誤,但它可能會導致以后出現意外行為 -

for(i=0;format[i]!='\0';i++) // convert to printf syntaxe
{
    if(format[i]=='{' && format[i+2]=='}') //check if it's {x}

您檢查當前位置是否是字符串的結尾,然后檢查當前位置之后的兩個字符是否有右括號,而不檢查字符串是否在下一個空格處結束 這可能會導致在為數組分配的內存之外進行讀取。 if(format[i]=='{' && (format[i+1]=='i' || format[i+1]=='s') && format[i+2]=='}')替換 if 語句if(format[i]=='{' && (format[i+1]=='i' || format[i+1]=='s') && format[i+2]=='}')會避免這個問題。

暫無
暫無

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

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