字符串的空间分配

见到一个题目,说是面试题:
题目:请分析程序输出

include

include

int main()
{
char s[] = "abcdefghijklmnopqrstuvwxyz";
char d[] = "123";
strcpy(d, s);
printf("%s %s\n", s, d);
return 0;
}

运行一下
如果你已经有答案了,看看在Windows10,64位上 VS2017上的运行结果:


程序中断

从输出结果可以看到: d 输出了“abc....xyz”,而 s 则输出了d 的一部分 “mno...xyz”

strcpy 是通过判断输入的实参 s 的结尾 ‘\0’来结束拷贝的,所以此处 d 里面会拷贝整个 s 的内容。所以 123 就被覆盖了。
但是,由于 d 的空间有限,所以会发生溢出。而这个溢出影响到了原本 s 存储的 “abc...xyz”,所以才出现
s 被截断的报错。


strcpy

这个题目的结果是 s 被截断,但是 s 的输出结果却是不一定的。得看系统给 d 分配的空间多少


拷贝前

拷贝后

由内存分配可以看到 分配给字符串 d 的空间是 12 个字节。所以 abcdefghijkl 12 个字节后,是 m开头


拷贝后的内存

为什么分配给 d 的是 12 个字节呢?
可以看到,每个字符串后面都跟了 8 个 “?”,也就是系统给每个字符串的结尾都会多增加 8 个字节的内存空间。
如果 s [] = "12345678",一共9个字节的话,会看到 “?”变成了 11 个。似乎有意先加 3 凑到 12 ,再加上 8 个字节。
也就是说,先对齐到 4 的倍数,再增加 8 个字节。到此为止,不再深究。
如有兴趣,以下图也许有些线索:


d被截断

你可能感兴趣的:(字符串的空间分配)