C 长字符串中的分段错误

C 长字符串中的分段错误,c,arrays,string,segmentation-fault,asprintf,C,Arrays,String,Segmentation Fault,Asprintf,我正在编写一个函数,它作为标准输出输出输出到,就像一个常规printf函数那样,但它需要使用{I}或{s}等指示符。我遇到的问题是,当format参数的字符串太长(大约23个字符)时,在调用vfprintf函数的那一行出现了一个分段错误 int mr_asprintf(const char *format, ...) { int i; char *newFormat = calloc(1,sizeof(char));

我正在编写一个函数,它作为标准输出输出输出到,就像一个常规printf函数那样,但它需要使用{I}或{s}等指示符。我遇到的问题是,当format参数的字符串太长(大约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
将很快开始在未分配的内存上跺脚。考虑到系统允许您在爆炸前扫描多达23个字符,当您使用
strcat()
将字符串填充到动态分配的1字节内存中时,输出字符串的长度将始终保持不变,并具有自行完成内存的终止空值。
for(i=0;format[i]!='\0';i++) // convert to printf syntaxe
{
    if(format[i]=='{' && format[i+2]=='}') //check if it's {x}