我正在学习C编程的基础知识,我想测试一些字符串的行。
这是我的代码:
int main(){
char a[] = "abc";
strcpy(a,"pqrst");
printf("%s; %d",a, sizeof(a));
}
我希望代码输出size = 6(p,q,r,s,t和' \ 0'),但它仍会打印size = 4。这是如何工作的?
答案 0 :(得分:4)
sizeof在编译时根据a
的声明计算,该声明有4个字符(3 + 1空终止符)。应该注意的是数组的大小和数组中字符串的长度不一样。
此外,副本已溢出缓冲区。您必须创建一个足够大的数组来保存要复制的字符串。
答案 1 :(得分:3)
sizeof(a)
在编译时进行评估。 a
的类型(部分由声明的char a[]
部分确定,部分来自"abc"
初始化程序)是“4个数组的数组”,因此sizeof(a)
计算为{ {1}}。 4
元素的值对结果没有影响。
顺便提一下,程序中的a
调用会导致缓冲区溢出。额外的字符写在内存中的某处,可能会导致不可预测的行为。
如果您使用strcpy
将字符串“z”复制到a
,则不会有任何未定义的行为,strcpy(a, "z");
会评估为strlen(a)
,但{{1}仍然是1
。
答案 2 :(得分:1)
您的strcpy
- 调用有缓冲区溢出(源比目标长两个字节),导致undefined behavior (UB)。
调用UB意味着在任何调用它的执行路径(包括此处包含所有路径),甚至在你到达之前之前没有任何理由可供选择。
如果修复UB,sizeof
为evaluated at compile-time for all but VLAs,给出参数的大小:数组(3个元素" abc" + 1隐式终止符" \ 0& #34;)char
。
答案 3 :(得分:1)
这一行
char a[] = "abc";
在堆栈上为4个字符的字符串创建空间。这和做的一样:
char a[4] = "abc";
当你这样做时:
strcpy(a, "pqrst");
它基本上是这样的:
int len = strlen("pqrst") + 1;
for (int i=0; i<len; ++i)
a[i] = "pqrst"[i];
显然,该代码将覆盖a
数组的边界。
基本上,听起来你希望C为你做额外的工作。这与C将会做的相反。