C语言里面的数组都是在编译的时候就分配好内存的吗?

yxm433 2010-08-03 09:35:04
C语言里面的数组都是在编译的时候就分配好内存的吗?

如果是在函数内部定义的数组呢?
void func()
{
int shuzu[SIZE];

}
...全文
1360 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
yzx714 2010-08-21
  • 打赏
  • 举报
回复
auto数组是运行时分配在stack上的,static是分配在静态数据区的
cao_julians 2010-08-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 bobo364 的回复:]
C语言里面的数组都是在编译的时候就分配好内存的吗?

我认为是编译时间分配好的

对于静态储存区的数据,在编译时就分配了内存地址(相对地址),在程序开始执行时变量就占用内存,直到程序结束时变量才释放内存。
[/Quote]
应该说是编译时“规划”好的(结构布局而已),在运行时按“规划”分配的。
NoneSec 2010-08-21
  • 打赏
  • 举报
回复
看看c语言的链接这部分的东西咯……
.data 段存放初始化的全局变量和已经初始化的局部静态(static)变量,.bss 段存放未初始化的全局变量和静态(static)局部变量,堆栈段存放局部的auto变量。
可以看看《c专家编程》的第六章 运动的诗章:运行时数据结构。
xdsamuel 2010-08-04
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 lightboat09 的回复:]
函数里是运行的时候分配在栈上的吧,我的理解
[/Quote]

正解,当调用到这个函数时,会把当前函数的局部变量压栈,这时候就会分配这个数组
jackyjkchen 2010-08-04
  • 打赏
  • 举报
回复
一堆装B的……
FatBigSea 2010-08-04
  • 打赏
  • 举报
回复
会汇编的话,dumpbin /disasm your.obj 真相就会出来。
zhh_kv 2010-08-04
  • 打赏
  • 举报
回复
内存分配方式有三种:
[1] 从静态存储区域分配。内存在程序 编译的时候就已经分配好,这块内存 程序 的整个运行期间都存在。例如全局变量, static变量。
[2]在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
[3]从堆上分配,亦称动态内存分配。 程序 在运行的时候用malloc或new申请任意多少的内存, 程序 员自己负责在何时用free或delete释放内存。动态内存的生存期由 程序 员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的 程序 会出现内存泄漏,频繁地分配和释放不同大小的堆空间将会产生堆内碎块

int a = 0; //全局初始化区
char *p1; //全局未初始化区
int main() {
int b; //栈
char s[] = \"abc\"; //栈
char *p2; //栈
char *p3 = \"123456\"; //123456\\0在常量区,p3在栈上。
static int c =0;//全局(静态)初始化区
p1 = new char[10];
p2 = new char[20];
//分配得来得和字节的区域就在堆区。
strcpy(p1, \"123456\"); //123456\\0放在常量区,编译器可能会将它与p3所指向的\"123456\"优化成一个地方。
}
xjing121 2010-08-04
  • 打赏
  • 举报
回复
临时变量应该是运行的时候才压栈的吧
辉歌 2010-08-04
  • 打赏
  • 举报
回复
楼主是个有钻研精神的同学,很值得赞扬。类似的问题,可以通过阅读相关书籍进行解答。很多问题都可以从书籍里系统的得到解决。下面列出来的,都是从书籍里回忆出来的综合,很有可能有不对的地方:

一个可执行文件被操作系统的加载器加载后,在进程环境里,会有4G空间的虚拟内存可供使用。而针对每一个线程,会初始化出一大片连续的内存空间作为栈区,这个大小,据说可以在编译的时候指定。同时,还会有一片堆区,一片已经初始化好数据的空间,一片没有初始化数据的空间,还有常量空间。除了栈区与线程相关,其他似乎是无关的,记不清楚了。

这些内存空间都有不同的属性,比如可读,可写,可执行等等。都是在加载的时候,操作系统做的事情。那加载器如何将程序中不同的变量部署到不同的区域呢?这就是靠可执行文件指示了。而可执行文件,就是通过编译器对源代码进行编译得到的。源代码是程序员写出来的,所以最终,还是程序员决定了变量的分布了。

编译器是什么呢?编译器就是把源代码编译成某种格式的文件。这种格式,就有一部分指定了各变量存在在哪里。因为操作系统不同,所以可执行文件的格式也不同,但基本大同小异都要满足上面的需求。我比较了解的windows下面的可执行文件格式PE格式。

针对源代码,就有以下几种情况:

1. 全局的未初始化的变量,如在某cpp文件的全局块里定义:
int x;
char s[100];

2. 全局的已初始化的变量,同样在某cpp文件的全局块里定义:
int y=1;
char ss[100]={"yesorno!"};

3. 以static关键字声明的全局变量,同样在某cpp文件的全局块里定义:
static int z=1;
static int a;

4. 在某语句中用new操作符申请的内存:
char * sz = new char[100];
5. 在某语句中用malloc等申请的内存:
char* sz = (char*)malloc( 100 );

6. 在函数里定义的局部变量,包括有初始化数据和没有初始化数据:
int x(void)
{
int z;
int y=1;
char sz[100];
char sss[100]={"dkjfkdjf"};
}

7. 在函数参数列表里定义的形参(关于形参,不深入讨论,形参是没有内存空间的):
int abc(int x,int y,struct XYZ x )
{
...
}

大约是上面几种情况了,class 变量也属于变量范围。

刚好可以和进程环境中的几个内存区域对应起来。
全局未初始化变量---> 一片没有初始化数据的空间
全局已初始化变量---> 一片已经初始化好数据的空间
static全局变量 ---> 一片已经初始化好数据的空间
new,malloc等动态分配 ---> 一片堆区
函数里定义的局部变量 ---> 栈区
函数参数 ---> 栈区

栈有栈顶栈底,一般来说,调用函数,都是通过将参数push到栈上,函数局部变量,也是放在栈上。以一个例子表现如下:
void foo()
{
int x=4;
int y=5;
bar(x,y);
printf(x);
}

现在模拟编译器的动作,当该函数被调用的时候,肯定是在某个线程里了。这个线程当然有栈空间。当调用这个函数的时候有栈底指针EBP,栈顶指针ESP:

int x=4 ==> 需要4个字节的栈空间,初始值为4
int y=5 ==> 需要4个自己的栈空间,初始值为5
计算得到该函数需要栈空间8个字节,则 esp = esp - 8 ,移动栈顶指针,开辟8个字节的栈空间。
mov esp , 5
mov esp - 4 ,4 初始化。

push 5 参数入栈 esp栈顶移动
push 4 参数入栈 esp栈顶移动
call bar

基本过程就是这样了。可能细节出错的比较多。大体意思应该是的。


yxm433 2010-08-03
  • 打赏
  • 举报
回复
在vc6.0试了一下,在函数test()里面定义数组,在运行到test()前,查看test()定义的数组是看不到的,要进去才能看到,test()执行完,数组就没了。
bobo364 2010-08-03
  • 打赏
  • 举报
回复
C语言里面的数组都是在编译的时候就分配好内存的吗?

我认为是编译时间分配好的

对于静态储存区的数据,在编译时就分配了内存地址(相对地址),在程序开始执行时变量就占用内存,直到程序结束时变量才释放内存。
赵4老师 2010-08-03
  • 打赏
  • 举报
回复
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编。)
ayw215 2010-08-03
  • 打赏
  • 举报
回复
[Quote=引用楼主 yxm433 的回复:]
C语言里面的数组都是在编译的时候就分配好内存的吗?

如果是在函数内部定义的数组呢?
void func()
{
int shuzu[SIZE];

}
[/Quote]函数内部的数组是运行时在站上分配----new出来的除外
pengzhixi 2010-08-03
  • 打赏
  • 举报
回复
非局部数组的话是编译期分配
小楫轻舟 2010-08-03
  • 打赏
  • 举报
回复
函数里是运行的时候分配在栈上的吧,我的理解

70,026

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧