请教有关存储类型与内存中的区域
请教问题,请看看,谢谢先!!!!!!!!
/*作用域生命期存储类型*/
#include <stdio.h>
#include <stdlib.h>
int a;
int *e;
typedef struct{
int a;
}str;
typedef struct{
int a;
}str1;
str aa;
int *aaa;
int aaaa[4];
int *ca;
//a,b static,cvariable
//e,fpointer
//aa,bbstruct
//aaa,bbbmalloc
//ca,cbcalloc
//aaaa,bbbbarray
void main()
{
static int b;
int c;
int *f;
str1 bb;
int *bbb;
int bbbb[4];
int *cb;
int i;
printf( "address,i\t%d\n ",&i);
puts( "//a,b static,cvariable ");
printf( "data\t ");
printf( "a,%d\tb,%d\tc,%d\n ",a,b,c);
printf( "address\t ");
printf( "a,%d\tb,%d\tc,%d\n ",&a,&b,&c);
puts( " ");
puts( "//e,fpointer ");
//printf( "data of the pointer point to\t ");
//printf( "e,%d\tf,%d\n ",*e,*f);//??? printf( "e,%d\tf,%d\n ",*e,*f); error
printf( "address of the pointer point to\t ");
printf( "e,%d\tf,%d\n ",e,f);
printf( "address of the pointer\t ");
printf( "e,%d\tf,%d\n ",&e,&f);
puts( " ");
puts( "//aa,bbstruct ");
printf( "data\t ");
printf( "aa,%d\tbb,%d\n ",aa.a,bb.a);
printf( "address\t ");
printf( "aa,%d\tbb,%d\n ",&aa.a,&bb.a);
puts( " ");
puts( "//aaa,bbbmalloc ");
aaa=(int *)malloc(sizeof(int)*4);
bbb=(int *)malloc(sizeof(int)*4);
for(i=0;i <4;i++)
{
printf( "data\t ");
printf( "aaa[%d],%d\tbbb[%d],%d\n ",i,aaa[i],i,bbb[i]);
}
for(i=0;i <4;i++)
{
printf( "address\t ");
printf( "aaa[%d],%d\t\tbbb[%d],%d\n ",i,&aaa[i],i,&bbb[i]);
}
puts( " ");
puts( "//aaaa,bbbbarray ");
for(i=0;i <4;i++)
{
printf( "data\t ");
printf( "aaaa[%d],%d\tbbbb[%d],%d\n ",i,aaaa[i],i,bbbb[i]);
}
for(i=0;i <4;i++)
{
printf( "address\t ");
printf( "aaaa[%d],%d\tbbbb[%d],%d\n ",i,&aaaa[i],i,&bbbb[i]);
}
puts( " ");
puts( "//ca,cbcalloc ");
ca=(int *)calloc(4,sizeof(int));
cb=(int *)calloc(4,sizeof(int));
for(i=0;i <4;i++)
{
printf( "data\t ");
printf( "ca[%d],%d\t\t\tcb[%d],%d\n ",i,ca[i],i,cb[i]);
}
for(i=0;i <4;i++)
{
printf( "address\t ");
printf( "ca[%d],%d\t\tcb[%d],%d\n ",i,&ca[i],i,&cb[i]);
}
}
运行:
address,i 1245016
//a,b static,c variable
data a,0 b,0 c,-858993460
address a,4361280 b,4361312 c,1245052
//e,f pointer
address of the pointer point to e,0 f,-858993460
address of the pointer e,4361284 f,1245048
//aa,bb struct
data aa,0 bb,-858993460
address aa,4361304 bb,1245044
//aaa,bbb malloc
data aaa[0],-842150451 bbb[0],-842150451
data aaa[1],-842150451 bbb[1],-842150451
data aaa[2],-842150451 bbb[2],-842150451
data aaa[3],-842150451 bbb[3],-842150451
address aaa[0],3616976 bbb[0],3617048
address aaa[1],3616980 bbb[1],3617052
address aaa[2],3616984 bbb[2],3617056
address aaa[3],3616988 bbb[3],3617060
//aaaa,bbbb array
data aaaa[0],0 bbbb[0],-858993460
data aaaa[1],0 bbbb[1],-858993460
data aaaa[2],0 bbbb[2],-858993460
data aaaa[3],0 bbbb[3],-858993460
address aaaa[0],4361288 bbbb[0],1245024
address aaaa[1],4361292 bbbb[1],1245028
address aaaa[2],4361296 bbbb[2],1245032
address aaaa[3],4361300 bbbb[3],1245036
//ca,cb calloc
data ca[0],0 cb[0],0
data ca[1],0 cb[1],0
data ca[2],0 cb[2],0
data ca[3],0 cb[3],0
address ca[0],3617120 cb[0],3617192
address ca[1],3617124 cb[1],3617196
address ca[2],3617128 cb[2],3617200
address ca[3],3617132 cb[3],3617204
Press any key to continue
├———————┤低端内存区域
│ …… │
├———————┤
│ 动态数据区 │
├———————┤
│ …… │
├———————┤
│ 代码区 │
├———————┤
│ 静态数据区 │
├———————┤
│ …… │
├———————┤高端内存区域
关于栈区和堆区,还有堆栈:
是否整个内存是个堆栈,然后里面包含栈区,堆区,全局区,代码区等等????
“栈是一种线性结构,堆是一种链式结构。”栈区是分配在内存较低地址的,堆区次之,全局区处于较高地址。
栈是向低地址扩展的数据结构,堆是向高地址扩展的。?????从以下看不出这一点,由bbbb[0]到bbbb[3],地址升高;由bbb[0]到bbb[3],地址也是升高。岂不都为向高地址扩展!!!!!!!!
|-----------------------------|-----低地址
|-----------------------------|
|首先栈区
|-----------------------------|i 1245016
|-----------------------------|???1245020这里存放什么?
|-----------------------------|bbbb[0],1245024
|-----------------------------|bbbb[1],1245028
|-----------------------------| bbbb[2],1245032
|-----------------------------| bbbb[3],1245036
|-----------------------------| ??1245040这里存放什么?
|-----------------------------|bb,1245044
|-----------------------------|f,1245048
|-----------------------------|c,1245052
|然后堆区
|-----------------------------| bbb[0],3617048?????
malloc先对aaa
作用,根据堆是向高地址扩
| 展,应该aaa地址较bbb低喔。
|-----------------------------|bbb[3],3617060
|之间以链连接
|-----------------------------|aaa[0],3616976
|
|-----------------------------|aaa[3],3616988
|
|-----------------------------|ca[0],3617120
|
|-----------------------------|ca[3],3617132
|
|-----------------------------|cb[0],3617192
|
|-----------------------------|cb[3],3617204
|再全局数据区
|-----------------------------|a,4361280
|-----------------------------|e,4361284
|-----------------------------|aaaa[0],4361288
|
|-----------------------------|aaaa[3],4361300
???依照读入次序,aa的地址是否因比aaaa高
|-----------------------------|aa,4361304
|-----------------------------|4361308 ??????这里存放什么
|-----------------------------|b,4361312静态局部变量
|-----------------------------|
|
|-----------------------------|高地址
全局变量的地址随读入持续而递增,那全局变量是怎样存于全局区的呢,也就是全局区是存放变量的流程是怎样的???是否如此:编译器从最后一个声明的全局变量开始分配空间(这个可用堆栈暂时保存),执行压栈操作,所以导致地址随读入次序递增。或者这是否可以说全局数据区的数据向高地址扩展??~~这是受函数读入函数参数也是从右往左读入萌发的思路,不知对否,各位大虾。^_^
另外:
malloc与calloc创建变量后若没有初始化,为什么一个数据为-842150451(未自动初始),一个数据为0(自动初始),这malloc和calloc有什么区别???我指的是它们的内部实现,而非表面的东西。
[解决办法]
malloc申请的内存块是不会初始化的,calloc申请的是会初始化清零的。这是C标准规定的。
malloc和calloc这种分配函数是分配在堆里的没错,但是他们的分配算法和具体的实现有关。例如,gcc在linux中提供的malloc函数可能在对小块内存申请时,用内存池的分配算法,而在对大块内存申请时,用伙伴算法。
现代操作系统一般都有虚拟内存,例如 32位window中号称提供了4G的平滑寻址能力。
各个段的载入方式和放置位置,是由操作系统作出的规定。
至于全局数据区中数据的存放顺序,那是编译器的喜好决定的,你无权干预。:)
[解决办法]
不知道lz所谓的可移植性指的是什么层级上的可移植性。
如果是指二进制文件的可移植性,那C是没有的,除非是同一体系兼容的系统。
如果是指源代码级的可移植性的话,是不会降低的。应为你到新的系统下会用该系统下的C编译器重新编译的。只要编译器对C标准兼容就可以了。
Java是能做到一次编译到处执行的,但C不行。例如在windows下的一个C程序,到linux下就要重新编译。 :)
[解决办法]
C语言数组是连续存放的,且索引小的在前,大的在后,即:
若a <b则,&(x[a]) < &(x[b])。
至于跳开的地方,也就是lz说得1245020等地方,是内存空穴。
编译器为了生成效率更高的代码,会有内存对齐规则。所以对于变量的位置关系不要做假设。