Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
malloc和BSS之间是否存在任何限制或位置差异?_C_Allocation_Linux_X86 64 - Fatal编程技术网

malloc和BSS之间是否存在任何限制或位置差异?

malloc和BSS之间是否存在任何限制或位置差异?,c,allocation,linux,x86-64,C,Allocation,Linux,X86 64,(为了回答这个问题,请忽略全局变量的利弊。) 全局变量是否与动态分配的内存位于同一内存空间中 例如,通常情况下,如果我想在内存中有一个大的多兆字节的数据结构,那么我需要malloc()这个数量,并从那里使用一个结构指针 我的问题是,这和仅仅将大型结构定义为全局结构在内存上有什么区别吗?我知道未初始化的全局变量在对象BSS中定义了它们的大小,但实际上不会占用对象文件中的空间,所以从某种意义上说,它们是在运行时分配的。但是,根据BSS的定义,对全局的大小有任何限制吗?他们是不是以malloc以外的方

(为了回答这个问题,请忽略全局变量的利弊。)

全局变量是否与动态分配的内存位于同一内存空间中

例如,通常情况下,如果我想在内存中有一个大的多兆字节的数据结构,那么我需要malloc()这个数量,并从那里使用一个结构指针

我的问题是,这和仅仅将大型结构定义为全局结构在内存上有什么区别吗?我知道未初始化的全局变量在对象BSS中定义了它们的大小,但实际上不会占用对象文件中的空间,所以从某种意义上说,它们是在运行时分配的。但是,根据BSS的定义,对全局的大小有任何限制吗?他们是不是以malloc以外的方式分配的?

这个答案适用于

静态对象没有分配给
malloc
(当然,您不能尝试
释放它们)。当二进制文件
exec
ed时,内核会为它们分配内存,同时还会分配程序的其余代码和数据。这通常称为“加载时”,而不是“运行时”,因为它发生在程序的任何代码实际执行之前。唯一的区别是分配给
.bss
的内存中没有填充从二进制文件加载的数据。与程序的其余部分一样,它通常是按需分页的,因此(归零)物理内存只有在实际读取或写入空间时才会分配,以后可能会交换到磁盘。它或多或少相当于一个匿名的
mmap

(我在这里使用“static”一词是指存储持续时间,而不是范围,它同样适用于C中的全局变量和
static
变量。对于位置无关的代码,这两个变量在内存位置上存在一些差异,我将不详细介绍,但它不会实质性地改变下面的信息。)

我假设您知道
malloc
通常是如何工作的,以及它是如何从操作系统获取内存的(通过
sbrk
或匿名
mmap
,通常后者用于大型对象),所以我不会对此进行描述

您可能会遇到的主要区别是,在默认编译器设置下,静态数据(包括bss)限制在2GB左右。Linux编译器工具链默认使用;所有代码和静态数据都是使用32位有符号RIP相对位移来访问的,因此任何两个这样的地址彼此之间的距离必须在2GB以内,因此实际上该限制适用于所有代码和静态数据的总大小。如果超过此限制,程序将无法编译或链接。(事实上,在一些测试中,如果您足够幸运地将一个对象放在数据末尾,则可能有一个对象比这个大,但这不太可能在实际程序中实现。)

您可以通过在编译时选择“中”或“大”代码模型来避免此限制,以便使用64位绝对地址,但折衷是它们会导致代码更大,效率更低,可能会影响整个程序。因此,除非您有非常特殊的原因想要静态地分配大型对象,否则动态地分配它可能会更好

对于非常大的分配,如果可移植性不是必需的,您可能更愿意直接使用匿名
mmap
,而不是
malloc
。这使您可以更好地控制何时将内存返回操作系统(使用
munmap
),还可以利用
mprotect
madvise
、大页面等功能,对MMU和分页机制进行更细粒度的控制

然而,总的来说,记忆就是记忆,不管它是如何获得的。

这个答案适用于

静态对象没有分配给
malloc
(当然,您不能尝试
释放它们)。当二进制文件
exec
ed时,内核会为它们分配内存,同时还会分配程序的其余代码和数据。这通常称为“加载时”,而不是“运行时”,因为它发生在程序的任何代码实际执行之前。唯一的区别是分配给
.bss
的内存中没有填充从二进制文件加载的数据。与程序的其余部分一样,它通常是按需分页的,因此(归零)物理内存只有在实际读取或写入空间时才会分配,以后可能会交换到磁盘。它或多或少相当于一个匿名的
mmap

(我在这里使用“static”一词是指存储持续时间,而不是范围,它同样适用于C中的全局变量和
static
变量。对于位置无关的代码,这两个变量在内存位置上存在一些差异,我将不详细介绍,但它不会实质性地改变下面的信息。)

我假设您知道
malloc
通常是如何工作的,以及它是如何从操作系统获取内存的(通过
sbrk
或匿名
mmap
,通常后者用于大型对象),所以我不会对此进行描述

您可能会遇到的主要区别是,在默认编译器设置下,静态数据(包括bss)限制在2GB左右。Linux编译器工具链默认使用;所有代码和静态数据都是使用32位有符号RIP相对位移来访问的,因此任何两个这样的地址彼此之间的距离必须在2GB以内,因此实际上该限制适用于所有代码和静态数据的总大小。如果超过此限制,程序将无法编译或链接。(事实上,在一些测试中,如果您足够幸运地将一个对象放在数据末尾,则可能有一个对象比这个大,但这不太可能在实际程序中实现。)

您可以通过在编译时选择“中等”或“大型”代码模型来避免此限制,因此