strcpy 给出分段错误
strcpy giving segmentation fault
考虑以下代码:
#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, '[=10=]'};
return s;
}
我想连接一个字符和一个字符串,但是我们没有这样做的函数,所以我定义了一个函数 chartoStr。另外 c_exp 和表达式变量不是只读模式,但是 strcpy() 给我分段错误。我也以任何方式尝试了其他功能,比如 strcat,但没有帮助。
如果有帮助,我会在 VS Code 中调试它。它打开 strcpy-sse2-unaligned.S
并在其中一行中显示分段错误。
是否需要 launch.json 或 task.json 个文件?我不认为他们可能有帮助,所以我没有用代码来解决这个问题,但是如果需要的话请告诉我。
您遇到了段错误,因为您正在返回局部变量的地址。
char s[2] = {c, '[=10=]'};
return s;
s
将在控制退出 chartoStr
函数后销毁。
编译器也发出同样的警告
warning: function returns address of local variable [-Wreturn-local-addr]
return s;
^
您不需要strcpy
复制您可以直接分配的单个字符。
要解决您的问题,您可以尝试以下方法。
char *chartoStr(char c)
{
char *s = malloc(2);
s[0] = c;
s[1] = '[=12=]';
return s;
}
工作完成后别忘了释放 s
。
chartoStr()
returns 一个在函数结束时不再可用的局部变量,由
回答
char s[2] = {c, '[=10=]'};
return s; // bad, UB
调用 chartoStr()
的替代方法是使用 compound literal(自 C99 起)在调用代码中创建 字符串。
// strcpy(c_exp, chartoStr(expressions[0]));
// v-----------------------------v---- compound literal
strcpy(c_exp, (char []){expressions[0], '[=11=]'});
一个不错的特性是没有昂贵的分配,也没有指向空闲的指针。 复合文字在块结束前有效。
请注意,代码可以通过在 cexpGen()
早期保存一次长度 size_t len = strlen(c_exp)
并使用它来追加来进行其他改进。
// strcpy(c_exp, chartoStr(expressions[0]));
c_exp[len++] = expressions[0];
c_exp[len] = '[=12=]';
其他问题
注意关于char c_exp[] = "1";
while (c_exp[strlen(c_exp) - 1]) > 10
是 未定义的行为 应该 strlen(c_exp)
return 0。也许 while ((len = strlen(c_exp)) > 0 && c_exp[len - 1]) > 10
?
if (now = 1)
始终为真。
考虑以下代码:
#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, '[=10=]'};
return s;
}
我想连接一个字符和一个字符串,但是我们没有这样做的函数,所以我定义了一个函数 chartoStr。另外 c_exp 和表达式变量不是只读模式,但是 strcpy() 给我分段错误。我也以任何方式尝试了其他功能,比如 strcat,但没有帮助。
如果有帮助,我会在 VS Code 中调试它。它打开 strcpy-sse2-unaligned.S
并在其中一行中显示分段错误。
是否需要 launch.json 或 task.json 个文件?我不认为他们可能有帮助,所以我没有用代码来解决这个问题,但是如果需要的话请告诉我。
您遇到了段错误,因为您正在返回局部变量的地址。
char s[2] = {c, '[=10=]'};
return s;
s
将在控制退出 chartoStr
函数后销毁。
编译器也发出同样的警告
warning: function returns address of local variable [-Wreturn-local-addr]
return s; ^
您不需要strcpy
复制您可以直接分配的单个字符。
要解决您的问题,您可以尝试以下方法。
char *chartoStr(char c)
{
char *s = malloc(2);
s[0] = c;
s[1] = '[=12=]';
return s;
}
工作完成后别忘了释放 s
。
chartoStr()
returns 一个在函数结束时不再可用的局部变量,由
char s[2] = {c, '[=10=]'};
return s; // bad, UB
调用 chartoStr()
的替代方法是使用 compound literal(自 C99 起)在调用代码中创建 字符串。
// strcpy(c_exp, chartoStr(expressions[0]));
// v-----------------------------v---- compound literal
strcpy(c_exp, (char []){expressions[0], '[=11=]'});
一个不错的特性是没有昂贵的分配,也没有指向空闲的指针。 复合文字在块结束前有效。
请注意,代码可以通过在 cexpGen()
早期保存一次长度 size_t len = strlen(c_exp)
并使用它来追加来进行其他改进。
// strcpy(c_exp, chartoStr(expressions[0]));
c_exp[len++] = expressions[0];
c_exp[len] = '[=12=]';
其他问题
注意char c_exp[] = "1";
while (c_exp[strlen(c_exp) - 1]) > 10
是 未定义的行为 应该 strlen(c_exp)
return 0。也许 while ((len = strlen(c_exp)) > 0 && c_exp[len - 1]) > 10
?
if (now = 1)
始终为真。