| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6032 人关注过本帖, 2 人收藏
标题:普通的变量是在编译时还是在运行分配内存单元的?
只看楼主 加入收藏
zhenhang
Rank: 1
等 级:新手上路
帖 子:18
专家分:2
注 册:2009-2-3
结帖率:80%
收藏(2)
 问题点数:0 回复次数:14 
普通的变量是在编译时还是在运行分配内存单元的?
谭浩强《C程序设计》第二版中有以下文字描述,我觉得近似乎矛盾了,普通变量的存储单元是什么时候分配的?全局变量的情况又是怎么样的呢?

pg40  “第一个变量被指定为一确定的类型,在编译时就能为其分配相应的存储单元。”

pg201 “如果在程序中定义了一个变量 ,在编译周日就给这个变量分配内存单元。”

pg173 “函数中的局部变量,如不专门声明为static类型存储类别,都是动态分配存储空间的,数据存储在动态存储区中。函数中的形参和函数中定义的变量,都属此类,在调用该函数时系统会给它们分配存储空间,在函数调用结束时就自动释放这些存储空间。”
搜索更多相关主题的帖子: 内存 运行 编译 单元 变量 
2010-02-11 11:50
木瓜君
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:67
专家分:144
注 册:2009-10-17
收藏
得分:0 
写了个程序,不知道你看不看懂~
程序代码:
#include <stdio.h>
#include <stdlib.h>
struct Test            //Test结构体
{
    int data;
    struct Test *next;
};
void test()
{
    int TestNum1 = 1;   //局部变量,生存期是函数开始到函数结束;
    static TestNum2 = 1;  //静态局部变量,函数结束时不会消失;
    TestNum1++;
    TestNum2++;
    printf("Number1 = %d\n",TestNum1); 
    printf("Number2 = %d\n",TestNum2); 
}
void main()
{
    int num = 0;           //确定类型,程序编译时自动分配空间
    struct Test *p;             //指针类型,它如果要指向结构体,就要给它分配空间;
    p = (struct Test *)malloc(sizeof(struct Test));  //手动分配空间;否则会出错
    test ();                 
    test ();
}
//调用两次test函数,运行得TestNum1两次运行都为2;TestNum2第一次为1,第二次为3;可知TestNum2在函数结束时没有释放储存空间
2010-02-11 16:49
zhenhang
Rank: 1
等 级:新手上路
帖 子:18
专家分:2
注 册:2009-2-3
收藏
得分:0 
谢谢您的回复,您举例的程序我是能够看懂的。我现在不解的问题是,如果auto型的局部变量是在编译时分配内存的(也就是分配个内存地址),
那么在整个程序运行的过程中这个空间不就不可以由其它的数据占用了,甚至出现一种极端的情况是这个程序运行前,该地址就已经被其他程序占用了。
出现这种情况怎么办,是不是采取相对地址
2010-02-11 18:39
zhenhang
Rank: 1
等 级:新手上路
帖 子:18
专家分:2
注 册:2009-2-3
收藏
得分:0 
也就是说分配的是相对地址!!!!
2010-02-11 18:40
木瓜君
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:67
专家分:144
注 册:2009-10-17
收藏
得分:0 
相对地址?
如果没空间,程序应该会出错~~
你的观点是不是“程序分配空间时,变量有一个固定的地址”?
程序分配变量空间应该是从未利用的内存中划分的,变量地址不固定~程序运行后,变量才产生一个地址
2010-02-11 19:15
zhddragon
Rank: 5Rank: 5
等 级:职业侠客
帖 子:208
专家分:346
注 册:2009-5-14
收藏
得分:0 
回复 楼主 zhenhang
在c程序里只有全局和静态变量有固定的逻辑地址(通常存在于数据段中),而所有局部变量的逻辑地址是运行时确定的,局部变量都是在运行时从栈分配的内存。

在编译时产生的目标文件都是从地址0开始的,在连接时将各个目标文件进行符号替换,这时会修改相应的地址,最后产生一个从地址0开始的可执行文件。在该可执行文件中的地址称为逻辑地址,也就是在c中所说的内存地址。在运行时加载器会把可执行程序(通常是可执行程序的一部分)加载到某个不定的内存区域中(每次加载到的物理内存地址不一定相等),这时如果使用逻辑地址进行寻址,那么逻辑地址会先通过分段单元装换成线性地址,然后线性地址通过分页单元(在这会使用到页表)转换成实际的物理地址。(这里以x86为原型)

身体是玩命的本钱
2010-02-11 22:16
zhenhang
Rank: 1
等 级:新手上路
帖 子:18
专家分:2
注 册:2009-2-3
收藏
得分:0 
回复 6楼 zhddragon
这个问题我感到非常苦恼,您能否留下QQ什么的联系方式,我想进一步向您讨教!!!我的QQ是920035025。
2010-02-11 23:46
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
所谓分配了空间,就是给它留个地。不用深究这个问题我觉得,这个问题我觉得老谭瞎讲,说得根本不清楚。
2010-02-12 09:46
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
6 楼说的那些是对的,但这些不是从 C 语言这个层面讨论的。他说了编译后的链接的一些知识,还说了一些寻址相关的东西。反正会的多了,这种确实不是问题。

楼主要想知道的稍多一些的话,学学 汇编语言 可能好一些。所谓变量的概念,在那之后可能就更清楚了。
2010-02-12 09:51
Kid_X
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:216
专家分:515
注 册:2007-10-8
收藏
得分:0 
全局变量存放在全局数据段中,这些变量的地址在编译后就应该确定了。
局部变量则是存放在堆栈中,通过栈顶地址加上偏移来寻址。
当然,这儿讲得简单了点,实际的还要复杂些。


学了汇编和指令寻址之后,你就会有更深入的了解。
2010-02-13 13:37
快速回复:普通的变量是在编译时还是在运行分配内存单元的?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.013052 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved