eXile 的专栏

一个小疑问:C++头文件中的静态全局变量

  一般来说,静态全局变量只应该定义在实现文件中,但有时由于一些特殊的目的,也可能定义在头文件中。比如在有些标准库的实现中,就用这种方法来初始化标准流cin, cout,或者在在tr1库中,也用这种方法来定义占位符。每一个包含该头文件的实现文件中都拥有该变量的一份拷贝,这些变量放在运行体的data段或者bss段。
   比如下面这个变量定义在一个头文件中:
static int data[1024*1024];
   我把这个文件同时包含在几个cpp文件中,按我的理解,这个程序占用的内存应该显著增大,但是,从实际运行结果来看,并没有变化,生成的exe文件大小也没有变化,这是因为延迟加载呢,还是被编译器优化掉了?有没有明白的达人解释一下。


posted on 2009-01-09 11:42 eXile 阅读(6285) 评论(19)  编辑 收藏 引用 所属分类: C/C++

评论

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 11:57 bug

静态变量只会生成一份的吧.
就好像你在类中放了一个静态成员变量,你初始化多个类,而静态成员变量却永远指向同一个地址  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 11:57 饭中淹

你可以测试下,在不同的cpp里面输出这个变量的地址,就什么都清楚了。

  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 11:58 bug

一般情况都是在cpp里放定义,在头文件中用extern 外部声明而已.  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 11:59 eXile

@飘雪

静态全局变量是不用的,它的作用域只是该文件,声明没有意义  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 12:00 eXile

@饭中淹
我测试过,地址是不同的  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 12:05 eXile

@bug
会生成多份的,这和类的静态变量是不一样的  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量[未登录] 2009-01-09 12:21 steven

我测试过,多加一个cpp,内存是会涨上去的,前提是给data拷贝数据。
//main.h

#ifndef STATICHEADER_H_
#define STATICHEADER_H_

static int point[1024*1024*10];

#endif

//main.cpp
#include "main.h"
#include "stdio.h"
int main()
{
getchar();
return 0;
}

//main1.cpp
#include "main.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"

static int outPrint()
{
memset(point,0,sizeof(point));
printf("%p,%p\n",point,outPrint);
return 0;
}
static int x=outPrint();

把main1.cpp拷贝多份,然后编译运行,就可以看到每增加一个cpp,内存会涨很多的。  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 12:21 沈臻豪(foxtail)

我觉得是延迟加载,优化貌似没办法解决这个问题的。你看看两个版本运行时的内存占用情况怎么样  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 12:29 了修

应该是进行了编译优化:内存折叠 了 这个在Thinking in C++中有描述
当你在取不同的文件取它的地址的时候,这个时候要建立一个临时变量,这个时候文件大小会发生变化。做下测试吧,偶现在没有机器了,没办法做……
嘿嘿 做好了 发份邮件给我吧:iHorn@163.com  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 12:33 eXile

看来确实是这样的,只有定义,是不会加载内存的,只有在实际使用时,才会加载。编译优化不太可能。  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 13:08 Herb

如果不是类中的静态变量,那么它和C的静态量沒什么区别。  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 13:27 啸天猪

这不是编译器的问题,而是OS的virtual memeory管理机制导致的

数据在实际使用之前,是不会占用内存的——缺页异常处理程序会为数据分配需要的内存。

  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 14:05 eXile

@啸天猪
老兄说到点子上了。  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-09 16:49 dev.zhu

这种很常见, 一般都是 宏
为了不使用全局变量而已  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-13 09:54 梦在天涯

static的应有一份!怎么会有不同的地址那!不使用之前是不分配的,这个倒是有可能啊!  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-14 10:23 dev.zhu

@梦在天涯
建议你看看C语法
  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-15 17:27 abettor

首先,对所有的CPP来讲,实际上是同一个东西,大家共用一个空间。
其次,编译出来的exe文件中没有这块1024*1024的空间存在,只是一个记号;只有系统运行这个文件,也就是变成进程后,系统才会在内存中分配这块空间。要清楚程序与进程的关系。  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2009-01-15 17:30 abettor

@abettor
补充一句,“运行体的data段或者bss段”,这里很明显,你所说的“运行体”是进程。研究PE文件格式,你会发现他不区分code段、data段等等概念,因为他是程序,不是进程。  回复  更多评论   

# re: 一个小疑问:C++头文件中的静态全局变量 2012-09-26 09:50 ligand

楼上说得对。楼主没有研究过.exe文件(即PE格式)的基本知识。编译器与链接器在生成exe文件时,时把指令、数据、元信息组织成性质与用途不同的section。例如,程序指令一般放在.text或者.code这个section中;只读(不能修改的)数据放在了.rdata中;未初始化的全局变量放在了.bss中;需要初始化的全局变量放在了.data中;此外,还有重定位信息使用的.reloc、线程局部存储使用的.thread等等。。。

对于不需要初始化的全局变量所存放的section,实际上并不占用exe的实际文件空间。只是在section table中登记一个装入内存时的尺寸数值、在内存中的开始(虚)地址。在exe装入内存成为一个进程时,这些未初始化全局变量才会实际分配占用内存。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2009年1月>
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

统计

常用链接

留言簿(18)

随笔分类

随笔档案

服务器编程

搜索

最新评论

阅读排行榜

评论排行榜