c - 长字符串中的段错误

标签 c arrays string segmentation-fault asprintf

我正在编写一个打印为标准输出的函数,就像常规 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 语句替换为 if(format[i]=='{' && (format[i+1]=='i' || format[i+1]=='s') && format[i +2]=='}') 会避免这个问题。

关于c - 长字符串中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49710909/

相关文章:

c - 指针和 malloc ....此代码段中的错误

java - Java 中的对象类型和引用数组

C 程序输出数组列表,然后交换列表之间的元素并再次输出它们

c# - 在字符串出现后删除文本

Windows 窗体应用程序中的 C# 字符串缺少字符

Ruby:每X个字符插入空格

c - OpenGL 照明斗争

c - 消息队列不接受 0 作为参数

c - 打开 Watcom 错误 E1127 "Type required in parameter list"

Java字符串越界的愚蠢行为