考虑以下代码:
#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文件?我认为它们可能无济于事,所以我没有在代码中填写问题,但请告诉我是否需要它们。
答案 0 :(得分:3)
chartoStr()
返回一个在函数末尾不再可用且由@kiran Biradar
char s[2] = {c, '\0'};
return s; // bad, UB
调用chartoStr()
的一种替代方法是使用compound literal(自C99开始)在调用代码中创建 string 。
// strcpy(c_exp, chartoStr(expressions[0]));
// v-----------------------------v---- compound literal
strcpy(c_exp, (char []){expressions[0], '\0'});
一个不错的属性是,没有昂贵的分配,也没有免费的指针。 复合文字有效期至程序段结束。
请注意,代码可以通过在size_t len = strlen(c_exp)
的前面保存一次长度cexpGen()
并使用它来追加来进行其他改进。
// strcpy(c_exp, chartoStr(expressions[0]));
c_exp[len++] = expressions[0];
c_exp[len] = '\0';
其他问题
注意char c_exp[] = "1";
关于@alk
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 :(得分:1)
由于返回的是局部变量的地址,因此出现段错误。
char s[2] = {c, '\0'};
return s;
s
将在控件退出chartoStr
函数后被销毁。
编译器也警告相同
警告:函数返回局部变量[-Wreturn-local-addr]的地址
return s; ^
您不需要strcpy
复制可以直接分配的单个字符。
要解决您的问题,您可以尝试以下操作。
char *chartoStr(char c)
{
char *s = malloc(2);
s[0] = c;
s[1] = '\0';
return s;
}
完成工作后,别忘了释放s
。