C++ 什么是c/c++;数据段和堆栈大小?

C++ 什么是c/c++;数据段和堆栈大小?,c++,linux,gcc,stack,data-segment,C++,Linux,Gcc,Stack,Data Segment,我读到它取决于编译器和操作系统架构。如何在使用GCC作为编译器的Linux系统上找到数据段和堆栈最大大小?段是一种组织可执行文件所需内容的方法 数据段通常用于可执行文件使用的任何数据(无需从外部源输入)。某些数据段可能包含字符串文字或数字常量 许多可执行文件使用堆栈存储函数局部变量、语句块局部变量、返回地址和函数参数。C或C++语言不需要堆栈;这只是一个方便的数据结构 堆栈大小可以是分配给堆栈的容量、驻留在堆栈上的元素数或堆栈占用的内存量 许多平台都有堆栈的默认大小。由于平台不同,您需要阅读工具

我读到它取决于编译器和操作系统架构。如何在使用GCC作为编译器的Linux系统上找到数据段和堆栈最大大小?

段是一种组织可执行文件所需内容的方法

数据段通常用于可执行文件使用的任何数据(无需从外部源输入)。某些数据段可能包含字符串文字或数字常量

许多可执行文件使用堆栈存储函数局部变量、语句块局部变量、返回地址和函数参数。C或C++语言不需要堆栈;这只是一个方便的数据结构

堆栈大小可以是分配给堆栈的容量、驻留在堆栈上的元素数或堆栈占用的内存量

许多平台都有堆栈的默认大小。由于平台不同,您需要阅读工具的文档,了解如何设置堆栈大小以及默认容量

如何在使用GCC作为编译器的Linux系统上找出数据段和堆栈的最大大小

这些限制可以理解为的
RLIMIT_数据
RLIMIT_堆栈
资源限制

在命令行中,您可以使用
ulimit
命令查找系统的以下限制:

$ ulimit -s # stack
8515
$ ulimit -d # data
unlimited
您可以通过修改来更改系统限制

更多信息请访问:

在Linux/x86-32上,新线程的默认堆栈大小为2 MB。在NPTL线程实现下,如果程序启动时的RLIMIT_堆栈软资源限制具有“unlimited”以外的任何值,则它将确定新线程的默认堆栈大小。使用pthread_attr_setstacksize(3),可以在用于创建线程的attr参数中显式设置stack size属性,以获得默认值以外的堆栈大小

以及:

--堆栈保留

--堆栈保留,提交

指定要保留(和可选提交)的内存字节数,以用作此程序的堆栈。默认值为2MB保留,4K提交。[此选项特定于链接器的i386 PE目标端口]


让我来试验一下:创建文件“test.c”,如下所示:

int main (void) { return 0; }
section           size         addr
.text             1880   4299165696
.data              104   4299169792
...
$ nm test.x  | grep __size_of_stack_reserve__
0000000000020000 A __size_of_stack_reserve__
现在编译它,指定最大堆栈大小(只是为了方便在映射文件中查找此数字并确定符号名称,请参考它):

确定数据大小很简单:

size -A -d test.x
你会得到这样的结果:

int main (void) { return 0; }
section           size         addr
.text             1880   4299165696
.data              104   4299169792
...
$ nm test.x  | grep __size_of_stack_reserve__
0000000000020000 A __size_of_stack_reserve__
另外,“objdump-htest.x”也可以正常工作,但结果不太详细

这里有更多的部分(不仅仅是代码和数据),但这里没有堆栈信息。为什么?因为堆栈大小不是ELF节,所以它仅在加载要执行的程序后保留。您应该从文件中的某个(平台相关)符号中读取它,如下所示:

int main (void) { return 0; }
section           size         addr
.text             1880   4299165696
.data              104   4299169792
...
$ nm test.x  | grep __size_of_stack_reserve__
0000000000020000 A __size_of_stack_reserve__
正如编译时所述,大小为0x20000并不奇怪

我通过查看编译期间生成的output.map文件来确定符号名。我建议你也从看它开始

下一步,当您确实有一些未知文件a.out时,只需重复以下顺序:

size -A -d a.out
nm a.out | grep __size_of_stack_reserve__

用一个平台相关的符号替换它,这是您在上面描述的实验中确定的。

我将从查看GCC文档开始。告诉您的链接器打印一个映射文件。地图文件将列出所有线段及其大小。没有标准告诉链接器或编译器如何生成映射文件。您需要查阅工具文档。数据段最大大小,不知道是否有最大大小。如果有,那就没什么意义了。最大堆栈大小: