关于C语言字符串长度的有关问题

关于C语言字符串长度的问题
C/C++ code

#include"stdio.h"
#include"string.h"
void main()
{
    char s1[4]={'a','b','c','d'},ch1='#',ch2='*';
    char s2[9]="1234";
    printf("%d\n",strlen(s1));
    printf("%d\n",strlen(s2));
}


运行结果s1=7,s2=4.


关于s1为什么等于7,本人很困惑!!
对于s1,ch1,ch2,和s2这样的局部变量,应该是顺序存储在栈区域。所以他们的地址应该是紧挨着的,所以s1应该是等于10呀(在s2结尾遇到终结符0)。为了便于具体分析,我查看了他们的地址如下:

+ s2 0x0018ff30
+ &ch2 0x0018ff3c
+ &ch1 0x0018ff40
+ s1 0x0018ff44 

看了地址,我发现这些变量的地址不是紧挨着的。比如像ch2的地址和s2的地址隔了12个字节,但是s2本事只占用了9个字节。那三个字节呢?  


请问大侠们具体是怎么回事。

------解决方案--------------------
strlen会根据结束符'\0'来计算长度,因此s1的长度取决于当时内存中的数据何时出现'\0'。
------解决方案--------------------
堆栈布局并没有标准,编译器可以从性能上考虑进行调整,比如分配大小被圆整为CPU字长的倍数,保证变量首地址都是字长对齐的,如9圆整为12

对于x86 CPU,这样做能提高效率,对于ARM等RISC,这样做是必须的,arm无法读写不对齐的内存