由于初学,高手见笑了!历时两天,起因一个错误的程序,经过查书,网页查询,几个程序分析,最后自己编程验证,最后得到结果。遂写此文,以作见证!以下是过程。
首先看第一个程序:
#include <stdio.h>
#include <string.h>
int main() {
char a[1000];
int i;
for(i = 0; i < 1000; i++)
a[i] = -1 - i;
printf("%d/n", strlen(a));
return 0;
}
输出结果是255.原因自然很简单。就是strlen遇到/0退出。可以在程序中加循环输出a[i]得到验证。
下面是第二个程序:
#include <stdio.h>
#include <string.h>
int main()
{
char s1[10] = {'m','o','b','i','l'};
char s2[20] = {'a','s','n','i','/0','C','+','+'};
char s3[6] = {'i','s','o','n','+','+'};
printf("%d/n",strlen(s1));
printf("%d/n",strlen(s2));
printf("%d/n",strlen(s3));
return 0;
}
程序在VC6.0下的运行结果为:
5
4
12
有高手作答:
第一个不用说当然是:5
第二个是4,是因为数组里有/0的缘故,想必很多人都很清楚!!
我主要说的是第三个,为什么是12(跟楼主的一样!)
首先在栈中,对数组的分配是以4个字节为分配粒度的,即s1在实际的内存中分配了12(10+2)个字节,s2分配了20个字节,s3分配了8(6+2)个字节,由于strlen是根据'/0'来计算长度的,即依次从头开始向后搜索内存里的字节数,直到碰到某个字节的值是0为止,s1,s2,s3在线里的结构是:s3s2s1所以搜完s3以后没碰到0继续向后即搜向s2,恰好s2里的第五个字节值是:0,所以计算出来的值就是:8+4=12.
不信可以在s2里前面加一个字符,结果会是:13
但是在visual studio2008中第三个结果却是20.为什么?
下面看第三个程序:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char a[]="123456789";
char b[]="123";
strcpy(b,a);
printf("%s/n%s/n",a,b);
system("PAUSE");
return 0;
}
为什么以上程序在VC中输出
123456789
123456789
在Dev c++中输出
56789
123456789
高手作答:
出现56789
123456789 原因是
拷贝前a,b在内存中的情况为:
1 -------b
2
3
‘/0’
1--------a
2
3
4
5
6
7
8
9
‘/0’
拷贝后为:
1---------b
2
3
4
5---------a
6
7
8
9
'/0'
7
8
9
‘/0’
用printf输出字符串的时候,是以‘/0’为结束标记的,
则输出的a为:56789
输出的b为:123456789
在visual studio2008中结果同vc一致同时设置断点监视a,b内存首地址可以看出b占内存12字节。改变程序把a赋值为“12345678912345”运行结果是45 12345678912345.与期望值相同。但问什么b分配地址为12字节呢?他的分配粒度又是多少呢?
查询许多网页,没有找到合适的回答。只好自己做实验验证。以下为试验程序:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i;
char a[]="12345678912345";
char b[]="123";
char c[]="123";
}
增加c是为了看从数组大小。以作验证。其实可以不要。此程序中我们更改b的大小。b[]=“1”时加/0其实是两个字节,内存占用12个字节。b[]="12","123"也是占用12个字节。但当b[]="1234""12345""123456""1234567"时内存占用16个字节。再次增大b的大小,可知当b中元素个数为9-12个时,内存占用20个。当b中元素个数为13-16个时,内存占用24个,当b中元素个数为17-20个时,内存占用28个。分析数据可知,在visual studio中字符数组内存分配粒度也为4个字节。但编译器又比实际占用多分配了8个字节。这样做可能是因为怕内存出错,以空间换稳定性吧。例如上面第三个程序,当a中元素比b大的数目不超过8个时,虽说b已经溢出,但并没有覆盖a中元素。结果还是对的。
现在还有一个问题就是第三段程序中dev c++的内存为什么是那样分配的?希望高手作答?