Chinaunix

标题: 【已解决】关于数组申请后的内存占用问题 [打印本页]

作者: -liupangzi-    时间: 2010-01-09 16:26
标题: 【已解决】关于数组申请后的内存占用问题
先贴这个Demo,代码写的不好,大家轻砸:
#include <stdio.h>

int main()
{

/*We Hope They Are All Together*/

int start = 0;
int i_am_start = 100;
float i_am_float = 3.1415926;
char i_am_char[20] = {34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53};
int end = 1;
int *pstart = &start;
int *pi_am_start = &i_am_start;
float *pi_am_float = &i_am_float;
char *pi_am_char = &i_am_char[0];
int *pend = &end;

printf("The Address of start is :       ------%ld\n",&start);
printf("The Address of i_am_start is :  ------%ld\n",&i_am_start);
printf("The Address of i_am_float is :  ------%ld\n",&i_am_float);
printf("The Address of i_am_char is :   ------%ld\n",&i_am_char[0]);
printf("The Address of end is :         ------%ld\n",&end);
printf("The Address of pstart is :      ------%ld\n",&pstart);
printf("The Address of pi_am_start is : ------%ld\n",&pi_am_start);
printf("The Address of pi_am_float is : ------%ld\n",&pi_am_float);
printf("The Address of pchar is :       ------%ld\n",&pi_am_char);
printf("The Address of pend is :        ------%ld\n",&pend);

printf("------------------------华丽的分割线------------------------\n");
printf("\n");
printf("------------------------华丽的分割线------------------------\n");

/*Display Datas In Memory We've Allocated*/

int count = 0;
char *p,*q,*r;
q = &i_am_char[0];
r = (char *)&i_am_float;

for(p = q;p < r;p++)
  {
     printf("The Value of p is:------%c,\t the Address of i_am_char[%d] is:------%ld\n",*p,count,p);
     count++;
  }

/*i_am_char[20]:What's Left Behind Me?*/

return 0;

}

我想查看这些变量在内存中的排列,问题是:我只申请了一个20个元素的数组,为什么数组和下一个变量之间有36个元素?打印出来的内容如图:

我用的是WinXP SP3+CodeBlocks,其中黄箭头之后的内容有什么另外的含义么?

贴一下各个变量的地址(在我机器上):
The Address of start is :          ------2359148
The Address of i_am_start is :  ------2359144
The Address of i_am_float is :  ------2359140
The Address of i_am_char is :  ------2359104

The Address of end is :           ------2359100
The Address of pstart is :        ------2359096
The Address of pi_am_start is : ------2359092
The Address of pi_am_float is : ------2359088
The Address of pchar is :         ------2359084
The Address of pend is :          ------2359080

麻烦大家了~~

[ 本帖最后由 -liupangzi- 于 2010-1-11 11:17 编辑 ]

Magical Snap - 2010.01.09 16.09 - 002.jpg (104.58 KB, 下载次数: 36)

Magical Snap - 2010.01.09 16.09 - 002.jpg

作者: mike79    时间: 2010-01-09 21:06
你觉得有什么问题?
你申请20个元素,系统保证分配给你20个元素的空间,但不保证只分配给你20个元素的空间。
或者说你的要求并不是“分配且仅分配20个元素的空间”
作者: -liupangzi-    时间: 2010-01-09 21:42
原帖由 mike79 于 2010-1-9 21:06 发表
你觉得有什么问题?
你申请20个元素,系统保证分配给你20个元素的空间,但不保证只分配给你20个元素的空间。
或者说你的要求并不是“分配且仅分配20个元素的空间”


我大概明白你的意思了
刚才用VS2008编译了一下,系统分配了28个,貌似是根据编译器不同而不同。

还有需要请教的是:

“分配但并不仅分配20个元素的空间”是出于什么目的呢?

谢谢!
作者: beepbug    时间: 2010-01-10 13:46
C/C++的数组,边界只是在地上划一条线,这边是我家,那边是你家,你不要过来。可他伸脚进来,并没有任何东西挡着他。和别的语言不一样。
因此猜想,这多留一些荒地,就不太容易冲到别人园子去,别人也不太容易进来。是不是为了这个?

首要问题是,你看实际地址,不能完全说明问题。C/C++标准没规定,你在源码里如何安排一连串的实体,在目的码里也得安排得一模一样。
你看内存的数据,你看它在哪个段,占多少空间,就行了。别去关心它们的次序和距离。因为这些,标准没规定。
标准非但没规定,还反对你这么想。譬如,你定义了一串int,你让一个int指针先指向第一个int,然后一次一次地++,能不能遍历所有int?
作者: prolj    时间: 2010-01-10 13:50
出于对齐
作者: wuexp    时间: 2010-01-10 19:32
原帖由 prolj 于 2010-1-10 13:50 发表
出于对齐


这个好
作者: -liupangzi-    时间: 2010-01-10 19:41
原帖由 beepbug 于 2010-1-10 13:46 发表
C/C++的数组,边界只是在地上划一条线,这边是我家,那边是你家,你不要过来。可他伸脚进来,并没有任何东西挡着他。和别的语言不一样。
因此猜想,这多留一些荒地,就不太容易冲到别人园子去,别人也不太容易 ...


谢谢。

刚开始我确实是这么猜想的,可能编译器不会像人一样偷懒,但打印出来的结果也表明,除了数组,其他的变量在内存中是按照申请的顺序排列的,所以有些想当然的当成是这样了~

如果不这样想,问题是:
1.如果编译器有理由不让这些变量按顺序排列,在不同机器上,或者使用不同的编译器打印出来的结果应该显示为:固定的两个变量之间的地址差应该是随机的,但结果不是这样,而且如果是生成debug的话编译器应该让他们挨在一起,毕竟给自己找麻烦是不明智的(个人见解,欢迎拍砖)。
2.我同学和我都用了vs2008,20个数组元素均占用了28个元素的地址,所以我猜这个应该和具体某个编译器的行为有关。
3.我在SUSE Enterprise下GCC4.3编译出来的结果是刚好占用了20个元素,如图:

Thank you for your time~

GCC4.3_1.jpg (111.95 KB, 下载次数: 30)

GCC4.3_1.jpg

GCC4.3_2.jpg (174.48 KB, 下载次数: 34)

GCC4.3_2.jpg

作者: -liupangzi-    时间: 2010-01-10 19:42
原帖由 prolj 于 2010-1-10 13:50 发表
出于对齐


你的意思是:
1.出于对齐 sucks.
2.出于对齐,you suck.

????
作者: -liupangzi-    时间: 2010-01-10 19:43
原帖由 wuexp 于 2010-1-10 19:32 发表


这个好


能不能说的明白一些啊?谢谢~
作者: 群雄逐鹿中原    时间: 2010-01-10 19:46
debug需要,检测数组越界。用-O2 和 -O0都编编看? 我从来都是靠猜想的,信则灵。
对齐一说无根据无迹象表明反之不对齐。
作者: -liupangzi-    时间: 2010-01-10 19:46
原帖由 beepbug 于 2010-1-10 13:46 发表
C/C++的数组,边界只是在地上划一条线,这边是我家,那边是你家,你不要过来。可他伸脚进来,并没有任何东西挡着他。和别的语言不一样。
因此猜想,这多留一些荒地,就不太容易冲到别人园子去,别人也不太容易 ...


恩,有空去看看标准,大家都在说,貌似很火啊~~
作者: -liupangzi-    时间: 2010-01-10 19:50
原帖由 群雄逐鹿中原 于 2010-1-10 19:46 发表
debug需要,检测数组越界。用-O2 和 -O0都编编看? 我从来都是靠猜想的,信则灵。
对齐一说无根据无迹象表明反之不对齐。


GCC没试过,一会去试试,不过vs2008_release显示的是没有规律,就连之前连续排列的非数组元素也不挨着了,所以就没仔细看。
作者: beepbug    时间: 2010-01-11 08:07
原帖由 -liupangzi- 于 2010-1-10 19:41 发表


谢谢。

刚开始我确实是这么猜想的,可能编译器不会像人一样偷懒,但打印出来的结果也表明,除了数组,其他的变量在内存中是按照申请的顺序排列的,所以有些想当然的当成是这样了~

如果不这样想,问题 ...

对不起,你没看懂我的意思。C/C++标准同样没规定分配变量的实际空间,必须是随机的。我的意思是,C/C++标准没规定:
1)源码中变量的顺序,就是目的码或实际运行时内存中的顺序。
这意思是,如果你自己搞一个编译器,可以将它们整得相同顺序,也可以有所不同,甚至完全搞乱。
2)如果源码里相邻的两变量在目的码里也正好相邻,标准也没规定它哥俩必须紧挨在一起。
也就是说,紧挨着,标准不反对,隔开的,标准也不反对。
其实,不光是C/C++,其它高级语言也没规定。如果连这些都规定死了,那它就不是高级语言了,因为它把高级语言最基本的特殊也取消了。
你以为的东西,只有汇编语言才是这样。
虽然有许多人说,C/C++不算很完备的高级语言,但是,在这方面,它还是不容置疑的。
请记住,C/C++是高级语言,这样你就不会去钻这个牛角尖了。
作者: -liupangzi-    时间: 2010-01-11 11:17
原帖由 beepbug 于 2010-1-11 08:07 发表

对不起,你没看懂我的意思。C/C++标准同样没规定分配变量的实际空间,必须是随机的。我的意思是,C/C++标准没规定:
1)源码中变量的顺序,就是目的码或实际运行时内存中的顺序。
这意思是,如果你自己搞一 ...


我想这回我是明白了~

可能上几个帖子我没说明白,不好意思。

谢谢!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2