strcpy给出分段错误

问题描述 投票:1回答:2

请考虑以下代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *cexpGen();
char *chartoStr(char c);

char c_exp[] = "1";
char expressions[2] = {'+', '-'};

int main()
{
    cexpGen();
    printf("%s", c_exp);
    return 0;
}

char *cexpGen()
{
    int now = 1;
    while ((c_exp[strlen(c_exp) - 1]) > 10)
    {
        if ((c_exp[strlen(c_exp) - 1]) == '+' || (c_exp[strlen(c_exp) - 1]) == '-')
        {
            strcpy(c_exp, chartoStr(((c_exp[strlen(c_exp) - 2]) + 1)));
            continue;
        }

        if (now = 1)
        {
            strcpy(c_exp, chartoStr(expressions[0]));
            now++;
            cexpGen();
        }

        if (now = 2)
        {
            strcpy(c_exp, chartoStr(expressions[1]));
            now++;
            cexpGen();
        }

        if (now = 3)
        {
            strcpy(c_exp, chartoStr(((c_exp[strlen(c_exp) - 1]) + 1)));
        }
    }
}

char *chartoStr(char c)
{
    char s[2] = {c, '\0'};
    return s;
}

我想连接一个cahracter和一个字符串,但我们没有这个功能,所以我已经定义了一个函数chartoStr。 c_exp和表达式变量也不是只读模式,但strcpy()给我分段错误。我也试过其他功能,比如strcat,哪个没用。

如果它有帮助,我在VS Code中调试它。它打开strcpy-sse2-unaligned.S并显示其中一行的分段错误。

是需要launch.json还是task.json文件?我不认为他们可能有所帮助,所以我没有完整的代码问题,但告诉我他们是否需要。

c string segmentation-fault character strcpy
2个回答
3
投票

chartoStr()返回一个在功能结束时不再可用的本地,以及@kiran Biradar的回答

char s[2] = {c, '\0'};
return s;  // bad, UB

调用chartoStr()的另一种方法是使用compound literal(自C99起)在调用代码中创建字符串。

// strcpy(c_exp, chartoStr(expressions[0]));
//            v-----------------------------v---- compound literal         
strcpy(c_exp, (char []){expressions[0], '\0'});

一个很好的属性是没有昂贵的分配,也没有指向free的指针。复合文字在块结束前有效。


请注意,代码可以通过在size_t len = strlen(c_exp)中提前保存长度cexpGen()并使用它来附加来进行其他改进。

// strcpy(c_exp, chartoStr(expressions[0]));
c_exp[len++] = expressions[0];
c_exp[len] = '\0';

其他问题

请注意@alk关于char c_exp[] = "1";

while (c_exp[strlen(c_exp) - 1]) > 10是未定义的行为应该strlen(c_exp)返回0.也许while ((len = strlen(c_exp)) > 0 && c_exp[len - 1]) > 10

if (now = 1)总是如此。 @user3386109


1
投票

您正在收到段错误,因为您正在返回本地变量的地址。

char s[2] = {c, '\0'};
    return s;

一旦控制退出s功能,chartoStr将被销毁。

编译器也发出同样的警告

warning:函数返回局部变量的地址[-Wreturn-local-addr]

 return s;
 ^

您不需要strcpy来复制您可以直接分配的单个字符。

要解决您的问题,您可以尝试如下。

char *chartoStr(char c)
{
    char *s = malloc(2);
     s[0] = c;
     s[1] =  '\0';
    return s;
}

工作完成后别忘了释放s

© www.soinside.com 2019 - 2024. All rights reserved.