static 局部变量存在那个位置?

小男孩与胖子 2011-07-12 10:11:53
如题


我自己查资料得出的结果是在静态区

但是有人跟我说是在堆区,这让我感到很诧异,这到底是怎么一回事?
...全文
2432 43 打赏 收藏 转发到动态 举报
写回复
用AI写文章
43 条回复
切换为时间正序
请发表友善的回复…
发表回复
南飞的心 2013-03-29
  • 打赏
  • 举报
回复
引用 34 楼 benben2301 的回复:
用错标签了,不好意思。。 Assembly code?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 TITLE b.c .386Pinclude listing.i……
#include <stdio.h> static int sc = 5; //静态变量 static int sd; int g_e; int g_f = 3; //全局变量 void main() { static int sg = 10; //静态变量 static int sh; int a = 25; //局部变量 int b; sh = 100; sd = 20; g_e = 30; b = 18; } ;---------------------------------数据段 start _DATA SEGMENT COMM _g_e:DWORD ;g_e _sc DD 05H ;sc _g_f DD 03H ;g_f _?sg@?1??main@@9@9 DD 0aH ;sg _DATA ENDS ;-------------------------------数据段 end 请问:g_e是未初始化的全局变量,不应该放在BSS SEGMENT中吗?为什么会放在DATA SEGMENT中啊???求解答
heycare 2011-07-18
  • 打赏
  • 举报
回复
static局部变量存放 分2种情况。 1.bss段。 主要是未初始化的static局部变量和全局变量或者初始化为0
2.data段主要是初始化不为0的static局部变量和全局变量
Frog1228 2011-07-14
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 babilife 的回复:]
全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 程序结束后由系统释放
[/Quote]
+1 那块区域叫做全局区或静态区。
xuan.ye 2011-07-14
  • 打赏
  • 举报
回复
需要看是类还是结构
guolie1989 2011-07-14
  • 打赏
  • 举报
回复
静态存储区。
cwhe007 2011-07-13
  • 打赏
  • 举报
回复
全都放在电脑里
uniqueroy 2011-07-13
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 tony2278 的回复:]

引用 7 楼 delandi 的回复:
堆区和栈区有啥区别


栈区:存局部变量,定义的参数,比如int,char之类的,在函数结束时,系统会自动收回存储单元。
堆区:new,malloc等动态开辟的存在堆,函数结束时,需要我们用delete、free手动释放存储区。
[/Quote]

学习了.
再补个静态区
全局变量和静态变量都存储在静态区。
分两块。一块是存已经初始化的。一块是没初始化的
asutk 2011-07-13
  • 打赏
  • 举报
回复
不可能在堆区。
看书:Computer Systems: A Programmer’s Perspective
ljhhh0123 2011-07-13
  • 打赏
  • 举报
回复
简单的说:是和全局变量放在一起的,只不过编译器通过更改变量名使之别的函数或本文件之外的程序不能访问。
xiaowanghappy 2011-07-13
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 runfriends 的回复:]

jvm把对象信息与成员属性值保存在堆内存
类信息包括接口定义、类定义、方法定义、static块、静态变量,都保存在方法区又叫代码段。这个区貌似不能gc,出现的OutOfMemberError PermGen overflow就是指要加载的字节码信息所需要的总内存大小已经超出这一区定义的最大值,可以在启动jvm时指定PermGen的最大值。
栈内存就是方法调用所占用的内存……
[/Quote]
++
zzcmx2008 2011-07-13
  • 打赏
  • 举报
回复
内存分配方式有三种:
(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
zzcmx2008 2011-07-13
  • 打赏
  • 举报
回复
静态存储区。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
  • 打赏
  • 举报
回复
用错标签了,不好意思。。

TITLE b.c
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif
PUBLIC _g_f
;---------------------------------数据段 start
_DATA SEGMENT
COMM _g_e:DWORD ;g_e
_sc DD 05H ;sc
_g_f DD 03H ;g_f
_?sg@?1??main@@9@9 DD 0aH ;sg
_DATA ENDS
;-------------------------------数据段 end
PUBLIC _main
;-------------------------------BSS段 start
;BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。
;注意和数据段的区别,BSS存放的是未初始化的全局变量和静态变量,数据段存放的是初始化后的全局变量和静态变量。
_BSS SEGMENT
_sd DD 01H DUP (?) ;sd
_?sh@?1??main@@9@9 DD 01H DUP (?) ;sh
_BSS ENDS
;------------------------------BSS段 end
_TEXT SEGMENT
_a$ = -4
_b$ = -8
_main PROC NEAR
; File b.c
; Line 10
push ebp
mov ebp, esp
sub esp, 8
; Line 14
mov DWORD PTR _a$[ebp], 25 ; 00000019H
; Line 17
mov DWORD PTR _?sh@?1??main@@9@9, 100 ; 00000064H
; Line 18
mov DWORD PTR _sd, 20 ; 00000014H
; Line 19
mov DWORD PTR _g_e, 30 ; 0000001eH
; Line 21
mov DWORD PTR _b$[ebp], 18 ; 00000012H
; Line 23
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END


  • 打赏
  • 举报
回复

#include <stdio.h>

static int sc = 5; //静态变量
static int sd;

int g_e;
int g_f = 3; //全局变量

void main()
{
static int sg = 10; //静态变量
static int sh;

int a = 25; //局部变量
int b;

sh = 100;
sd = 20;
g_e = 30;

b = 18;

}


反汇编结果:

TITLE b.c
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif
PUBLIC _g_f
;---------------------------------数据段 start
_DATA SEGMENT
COMM _g_e:DWORD ;g_e
_sc DD 05H ;sc
_g_f DD 03H ;g_f
_?sg@?1??main@@9@9 DD 0aH ;sg
_DATA ENDS
;-------------------------------数据段 end
PUBLIC _main
;-------------------------------BSS段 start
;BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。
;注意和数据段的区别,BSS存放的是未初始化的全局变量和静态变量,数据段存放的是初始化后的全局变量和静态变量。
_BSS SEGMENT
_sd DD 01H DUP (?) ;sd
_?sh@?1??main@@9@9 DD 01H DUP (?) ;sh
_BSS ENDS
;------------------------------BSS段 end
_TEXT SEGMENT
_a$ = -4
_b$ = -8
_main PROC NEAR
; File b.c
; Line 10
push ebp
mov ebp, esp
sub esp, 8
; Line 14
mov DWORD PTR _a$[ebp], 25 ; 00000019H
; Line 17
mov DWORD PTR _?sh@?1??main@@9@9, 100 ; 00000064H
; Line 18
mov DWORD PTR _sd, 20 ; 00000014H
; Line 19
mov DWORD PTR _g_e, 30 ; 0000001eH
; Line 21
mov DWORD PTR _b$[ebp], 18 ; 00000012H
; Line 23
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END

runfriends 2011-07-13
  • 打赏
  • 举报
回复
报歉,没注意是c++版。搞错了
微微の星光 2011-07-13
  • 打赏
  • 举报
回复
全局变量和静态数据都在全局数据区。
runfriends 2011-07-13
  • 打赏
  • 举报
回复
jvm把对象信息与成员属性值保存在堆内存
类信息包括接口定义、类定义、方法定义、static块、静态变量,都保存在方法区又叫代码段。这个区貌似不能gc,出现的OutOfMemberError PermGen overflow就是指要加载的字节码信息所需要的总内存大小已经超出这一区定义的最大值,可以在启动jvm时指定PermGen的最大值。
栈内存就是方法调用所占用的内存,基本类型变量和方法调用时所引用的各种对象地址保存在此处,以及方法调用产生的方法调用地址信息都保存在栈内存。如果方法调用层次过多,会发生OutOfMemoryError Stack Overflow。递归层数太多时可能会发生这一错误。jvm为每个线程创建一个栈,也就是说同一线程内的所有方法调用共用一个栈,从jdk6开始每创建一个线程默认为线程分配1M内存的栈。可以在启动jvm时指定栈内存的最大最小值。
堆内存保存java所有对象信息,包括成员属性和对象本身所占用的空间。一个Object对象占用8字节,也是一个没有任何属性的对象所占用的最小字节。Integer对象占用4+8字节,Long对象占用8+8字节。一个对象所占用的全部内存数是它在堆内存中占用的字节数+所有这个对象的引用所占用的字节数。jvm为每个引用分配4字节(32位机的内存寻址位数就是32位刚好4字节)。
一个jvm进程占用的内存总数是jvm自身消耗的内存+堆内存+所有栈内存的和+方法区所占用的内存。sun的jvm实现,hotspot严格区分这几部分内存,互不干扰。
通常说的gc就是回收堆内存。栈内存不需要回收,因为随着方法执行,不断伴随着入栈出栈,方法返回时,方法占用的栈内存就被自动释放了。jvm自身消耗的内存由jvm自己管理。方法区占用的内存似乎还不能回收,我也不确定,我看过的文章有不同的说法,有说直到jdk6还不能回收的,有说jdk5以前不能回收的。
yshf0325 2011-07-12
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 tony2278 的回复:]
引用 7 楼 delandi 的回复:
堆区和栈区有啥区别


栈区:存局部变量,定义的参数,比如int,char之类的,在函数结束时,系统会自动收回存储单元。
堆区:new,malloc等动态开辟的存在堆,函数结束时,需要我们用delete、free手动释放存储区。
[/Quote]
++
pathuang68 2011-07-12
  • 打赏
  • 举报
回复
全局变量和静态数据都在全局数据区。即使是函数内部的静态局部变量也是如此。
pathuang68 2011-07-12
  • 打赏
  • 举报
回复
加载更多回复(23)

69,364

社区成员

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

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