Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1097166
  • 博文数量: 242
  • 博客积分: 10209
  • 博客等级: 上将
  • 技术积分: 3028
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-12 09:27
文章分类

全部博文(242)

文章存档

2014年(1)

2013年(1)

2010年(51)

2009年(65)

2008年(124)

我的朋友

分类: C/C++

2009-02-16 20:58:27

程序片段 :

C代码

void mstrcat(char *s, char *t)  

 {            

s += strlen(s);  

         for(;*t!='\0';*s++=*t++);  

         *s = '\0';  

void mstrcat(char *s, char *t)

 

{

 

         s += strlen(s);

 

         for(;*t!='\0';*s++=*t++);

 

         *s = '\0';

 

}

这是一个字符数组连接的函数 .

()在测试程序中声明如下 :

C代码

int main(){

char a[] = "abcd";  

char b[] = "ef";  

char s[] = "ghijklmnopqrstuvwxyz";  

mstrcat(b, s);  

printf("after:%s\n", b);  

printf("after:%s\n", a);  

}

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.4VC6.0,得出2种不同的结果:

GCC(无异常产生):

after:efghijklmnopqrstuvwxyz
after:uvwxyz

得出结论: gcc每个字符按一个字节存储,并且相邻字符数组按照地址下降来存储,而一个数组内元素按照地址上升来存储. GCC依照16个字节对齐原则进行对齐处理(即不足16个字节的数组,按16个字节进行对齐存储)

VC6.0:(出现异常)

after:efghijklmnopqrstuvwxyz
after:ijklmnopqrstuvwxyz

得出的结论: VC6.0每个字符按一个字节存储,并且相邻字符数组按照地址下降来顺序存储 ,而一个数组内元素按照地址上升来存储. VC6.0依照4个字节对齐原则进行对齐处理(即不足4个字节的数组,4个字节进行对齐存储)

总结:

总之,这种处理方式是种不安全的处理方式,是否出现异常取决于是否有足够的已申请空间的支持.GCC中未出现异常是因为GCC按照16字节的对齐方式,32字节足以容纳连接后的字符数组b.而在VC中出现异常是因为VC按照4字节的对齐方式,4字节不能容纳b.

可预见的是:如果当b的字符数组长度大于32,GCC中也会出现异常.

 ()在测试程序中声明如下 :

同样在测试程序中如果声明如下

C代码

int main(){

char *c;  

char *d;  

c = "abcd";  

d = "efghi";    

mstrcat(c, d);  

printf("%s\n", c);  

}

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);

 那么,GCCVC(版本同上)中的结果如下:

GCC(出现异常):

abcdefghi

fghi

得出结论:对于未指定所指对象的指针,其地址是编译器任意指定的,而当指定其所指对象时,指针则存储的是所指对象的首地址(例如,指针c指向的是字符数 组"abcd"的首 地址),由于字符数组之间顺序存放,所以d指向的是5个字节("abcd"占用5个字节存储空间)后的位置,这里我们的看到的地址是升序的.

VC(出现异常):

未知。

得出结论:对于VC而言,其相邻指定给指针的字符数组并非顺序存储,但指针指向的位置仍然是所指对象的首地址.

出现异常的原因是:

显然对于d字符数组所需要的连续存储空间c是不满足的(不能操作未申请的存储空间).

ps.

(),即使使用c语言的标准字符串函数strcat,strcat(b,s)也会出现异常,可见标准函数也没有使用重新申请新空间的方式处理.

 

阅读(1242) | 评论(0) | 转发(0) |
0

上一篇:内存对齐

下一篇:汇编语言到机器语言ZZ

给主人留下些什么吧!~~