您的位置:首页 > 其它

visual studio中字符数组内存分配粒度大小与字符数组实际内存占用大小的确定过程

2009-12-05 14:17 435 查看
由于初学,高手见笑了!历时两天,起因一个错误的程序,经过查书,网页查询,几个程序分析,最后自己编程验证,最后得到结果。遂写此文,以作见证!以下是过程。

首先看第一个程序:

#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++的内存为什么是那样分配的?希望高手作答?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: