锁定老帖子 主题:C语言中字符数组的存储
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-01-08
最后修改:2009-01-08
<!----><!----> <!----> C 语言中字符数组的存储程序片段 :
void mstrcat(char *s, char *t) { s += strlen(s); for(;*t!='\0';*s++=*t++); *s = '\0'; }
这是一个字符数组连接的函数 . (一)在测试程序中声明如下 :
char a[] = "abcd"; char b[] = "ef"; char s[] = "ghijklmnopqrstuvwxyz"; char *c; char *d; mstrcat(b, s); /* 连接后的b */ printf("after:%s\n", b); /* a */ printf("after:%s\n", a); /* 各字符数组的首元素地址 */ printf("%d\n", (int)a); printf("%d\n", (int)b); printf("%d\n", (int)s); 分别在GCC3.4.4和VC6.0后,得出2种不同的结果: GCC: after:efghijklmnopqrstuvwxyz 得出结论(无异常产生): 每个字符按一个字节存储,并且相邻字符数组按照地址下降来存储,而一个数组内元素按照地址上升来存储. GCC依照16个字节对齐原则进行对齐处理(即不足16个字节的数组,按16个字节进行对齐存储)
VC6.0:(出现异常) after:efghijklmnopqrstuvwxyz
得出的结论: VC6.0: 每个字符按一个字节存储,并且相邻字符数组按照地址下降来顺序存储 ,而一个数组内元素按照地址上升来存储. VC6.0依照4个字节对齐原则进行对齐处理(即不足4个字节的数组,按4个字节进行对齐存储)
总结: 总之,这种处理方式是种不安全的处理方式,是否出现异常取决于是否有足够的已申请空间的支持. 在GCC中未出现异常是因为GCC按照16字节的对齐方式,即32字节足以容纳连接后的字符数组b. 而在VC中出现异常是因为VC按照4字节的对齐方式,4字节不能容纳b. 可预见的是:如果当b的字符数组长度大于32时,GCC中也会出现异常.
(二)在测试程序中声明如下 : 同样在测试程序中如果声明如下 char *c; char *d; c = "abcd"; d = "efghi"; printf("%d\n", (int)c); printf("%d\n", (int)d); mstrcat(c, d); printf("%s\n", c); 那么,在GCC和VC(版本同上)中的结果如下: GCC(出现异常): 402000
得出结论: 对于未指定所指对象的指针,其地址是编译器任意指定的,而当指定其所指对象时,指针则存储的是所指对象的首地址(例如,指针c指向的是字符数组"abcd"的首 地址),由于字符数组之间顺序存放,所以d指向的是5个字节("abcd"占用5个字节存储空间)后的位置,这里我们的看到的地址是升序的.
VC(出现异常): 4333604
得出结论: 对于VC而言,其相邻指定给指针的字符数组并非顺序存储,但指针指向的位置仍然是所指对象的首地址. 出现异常的原因是: 显然对于d字符数组所需要的连续存储空间c是不满足的(不能操作未申请的存储空间).
ps. 在(一)中,即使使用c语言的标准字符串函数strcat,strcat(b,s)也会出现异常,可见标准函数也没有使用重新申请新空间的方式处理.
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 3855 次