如果在C++应用程序中全局声明数据结构,那么它会占用堆栈内存或堆内存吗?
例如:
1 2 3 4 5 6
| struct AAA
{
.../.../.
../../..
}arr[59652323]; |
- 此外,全局变量和静态变量(在函数中)之间的区别是什么?他们必须为节目的生命而活…
- 同意,但他们的差异在于可达性
- @dspinozzi:全局变量的构造函数在main()之前调用,但是静态变量的构造函数在第一次调用函数时调用。这两种类型的变量通常存储在内存的同一部分中——我认为gcc将它们放在.data节中。
因为我对答案不满意,并且希望Sameer Karjatkar想学习的不仅仅是一个简单的是/不是答案,给你。
通常一个进程分配了5个不同的内存区域
代码-文本段
初始化数据–数据段
未初始化的数据–BSS段
堆
栈
如果您真的想了解保存在何处的内容,请阅读并将其添加到书签中:
编译器、汇编程序、链接器和加载器:一个简单的故事(看表W.5)
记忆中程序的解剖
- 这是否意味着未初始化的数据(BSS和已初始化的数据)是堆的一部分?
- 不,它们不是堆的一部分,它们在不同的区域,正如我的答案中所写的(5个不同的区域)。堆和堆栈占据文本和数据段上方的虚拟内存。
- 重要的一点是,当程序首次加载到内存中时,会分配BSS和数据段,并且它们的大小在运行时不会改变。相比之下,堆的内容在整个运行过程中是不稳定的,并且随着动态内存操作的执行而改变。
- 我认为让堆栈向下增长,让堆向上增长的想法是为了让它们可以以任何比例使用可用内存。但是,这不是通过在两者之间加载动态库来阻止的吗?
- 初始化指向空值的指针是进入数据段还是进入BSS段?route_t* tblhead = NULL;
问题就在这里。假设您有一个很小的C(++,它们处理的方式相同)程序,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| /* my.c */
char * str ="Your dog has fleas."; /* 1 */
char * buf0 ; /* 2 */
int main(){
char * str2 ="Don't make fun of my dog." ; /* 3 */
static char * str3 = str; /* 4 */
char * buf1 ; /* 5 */
buf0 = malloc(BUFSIZ); /* 6 */
buf1 = malloc(BUFSIZ); /* 7 */
return 0;
} |
这既不是在堆栈上分配的,也不是在堆上分配的。相反,它被分配为静态数据,并在大多数现代机器上放入自己的内存段。实际的字符串也被分配为静态数据,并放入正确思考机器的只读段中。
只是一个静态分配的指针;在静态数据中为一个地址留出空间。
在堆栈上分配指针,当main返回时,指针将被有效释放。由于字符串是常量,因此它与其他字符串一起分配在静态数据空间中。
实际分配与2完全相同。static关键字告诉您不在堆栈上分配它。
…但是buf1在堆栈上,并且
…内存不足的缓冲区空间在堆中。
顺便说一句,孩子们不在家里尝试这个。malloc有一个利息的返回值;您应该经常检查返回值。
例如:
1 2 3 4 5
| char * bfr;
if((bfr = malloc(SIZE)) == NULL){
/* malloc failed OMG */
exit(-1);
} |
- 错误定位的缓冲区空间与全局变量无关。只有指针是全局的。请不要再把人们弄糊涂了。
- 哦,别傻了。提问者显然不清楚去哪里了,所以我写了一个答案,旨在提高他的理解力。
通常这两者都不消耗。它试图将它们分配到一个内存段中,该内存段很可能保持不变的大小以供程序执行。它可能是BSS、堆栈、堆或数据。
- 通过编辑boot.ini文件,我们可以将虚拟内存扩展到3GB。和WISE一样,内存段也有设置吗?
- 这将是毫无意义的,因为静态分配内存的大小永远不会改变
两者都不。是数据区。
- 这取决于全局内存是以内联方式分配的,还是从应用程序中动态地全部分配的。
- 如果内存是动态分配的,那么它不是全局的(从全局变量的意义上说)。
- 这是有争议的:)
- 那么,如果它不在所有计划的范围内,从什么意义上说它是全球性的呢?!
- 我必须同意埃弗拉姆的观点。实际全局变量将位于.data/.bss节中。当然,在指针的情况下,它最终可能指向动态分配的内存,但我不会说指针本身是动态分配的。
- 我们讨论的是通过全局变量全局访问的已分配内存。实际上,编译器甚至可以选择在堆上而不是在固定内存块中分配预先分配的内存块(如果内存块太大)
- 如果全局变量将位于data/.bss节中,它将显示在堆内存消耗中。我的意思是它会在虚拟内存下记录它的内存消耗吗?
- 另一个值得注意的点是".data"部分仅是可执行文件(所以是微软的东西)。当然,在其他操作系统上也有类似的结构,但问题并不是关于PC开发的。
- @Philippe-重点是全局指针指向的数据不能视为全局数据。它甚至可以在程序执行期间更改(不同的函数可能会将全局指针重置到它们想要的任何位置)
- @philippe:。数据部分也不只是.exe。
全局内存在固定内存块或堆中预先分配,具体取决于应用程序如何分配:
1 2 3 4 5 6 7
| byte x[10]; // pre-allocated by the compiler in some fixed memory block
byte *y
main()
{
y = malloc(10); // allocated on the heap
} |
编辑:
这个问题令人困惑:如果我在C++应用程序中全局分配数据结构,它会占用堆栈内存或堆内存吗?
"分配"?这可能意味着很多事情,包括调用malloc()。如果问题是"如果我全局地声明和初始化一个数据结构",那么情况就不同了。
许多年前,当CPU仍在使用64K段时,一些编译器足够智能,可以从堆中动态分配内存,而不是在.data段中保留一个块(因为内存结构的限制)。
我想我太老了……
- 这就是语义。我想这值得投反对票
- 它说的是"在堆上分配",这是非常正确的。除非这个问题被标记为"新手"或"初学者",否则这应该是对正在发生的事情的充分提醒。
- @唐:不。全局的东西是指针,而不是它指向的内存。你可以随心所欲地处理记忆。也没有留下来跑完全程。有时甚至可以把它指向堆栈。
- 如果要从中吸取一个教训,那就是你应该避免回答那些问题的确切含义不清楚的问题。我的回答是正确的,只是有些人认为他们对一个词的解释足以否决一切不支持他们观点的东西。即使是现在,在被问到这个问题10个小时后,仍然不清楚OP是什么意思。
- 是的,这是我提出问题时的错误。我已经编辑过了
在C++中全局声明数据结构既不消耗堆内存,也不消耗堆栈内存。实际上,全局变量通常分配在一个数据段中,在整个程序期间,该数据段的大小保持不变。堆栈和堆通常用于在执行程序期间创建和销毁的变量。
全局对象本身将占用运行时或编译器在执行main之前为其保留的内存,这不是可变的运行时开销,因此既不是堆栈也不是堆。
如果对象的ctor分配内存,则它将在堆中,并且对象的任何后续分配都将是堆分配。
它取决于全局对象的确切性质,如果它是指针,或者整个对象本身是全局的。
全局变量位于堆中。这是一个特殊的案例,因为它们是为项目的生命而活的。
如果您是通过new或malloc显式地自己分配内存,那么它将在堆中分配。如果编译器正在分配内存,那么它将在堆栈上分配。
- 永远不会在堆栈上分配全局内存。堆栈仅用于局部变量和参数
- 当函数返回时,堆栈变量被"销毁"