Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.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/2/batch-file/6.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
C++ malloc和heap:用于存储大小和链表信息的额外内存?_C++_C_Memory_Malloc_Heap - Fatal编程技术网

C++ malloc和heap:用于存储大小和链表信息的额外内存?

C++ malloc和heap:用于存储大小和链表信息的额外内存?,c++,c,memory,malloc,heap,C++,C,Memory,Malloc,Heap,我有一个关于堆和malloc的简单问题: 当我们使用malloc分配一些内存空间时,如下所示: int *p; p = (int*) malloc (10*sizeof(int)); 它实际上在堆中分配了10个字。不过,我的问题是: 实际使用的内存空间实际上是10个单词 还是需要其他额外的空间来存储内存大小的值 或者,因为堆的结构是链表,所以是否有其他内存空间用于存储指向堆中列表的下一个节点的地址 是的,malloc的实现可以实际分配比您请求的内存多一点的内存,将分配内存的大小存储在分配内存的

我有一个关于
malloc
的简单问题:

当我们使用
malloc
分配一些内存空间时,如下所示:

int *p;
p = (int*) malloc (10*sizeof(int));
它实际上在堆中分配了10个字。不过,我的问题是:

实际使用的内存空间实际上是10个单词

还是需要其他额外的空间来存储内存大小的值


或者,因为堆的结构是链表,所以是否有其他内存空间用于存储指向堆中列表的下一个节点的地址

是的,
malloc
的实现可以实际分配比您请求的内存多一点的内存,将分配内存的大小存储在分配内存的开头,然后给您一个指向下一个内存地址的指针。当您在该指针上调用
free
时,分配器将返回一点,读取缓冲区的大小,并计算出实际需要释放多少缓冲区


当然,另一种可能的实现可以保留一个列表或一个字典,或者做一些完全不同的事情,只要它提供相同的指定行为。

内存分配取决于编译器库和操作系统

两种语言都没有规定可分配的最大内存量。您所能保证的就是所要求的尺寸

因此,如果有任何额外的内存分配,它将依赖于平台

此外,在分配更大的空间时,开销可能更小


尝试编写自己的内存分配器,看看需要什么,特别是在解除内存占用时。

当您使用
malloc
分配内存时,您得到的只是指向该内存中第一个地址的指针,并保证已为您的使用分配了这么多字节。如何分配和跟踪内存的细节取决于平台,您无法从程序中访问这些信息。因此,虽然额外的内存可能被分配用于开销目的,但您不能以跨平台的方式使用这些知识。

它完全依赖于实现

a) 它可以在每个分配的节点之前有几个字节,其中包含节点的大小、指向下一个节点的指针,可能还有前一个节点指针和节点的类型

b) 返回的项目可能除了其他分配之外没有其他内容。其他地方的结构可以通过位图或小型并行列表跟踪分配的内容和空闲的内容

c) 另一个变体提供了几个固定大小的块数组。一个阵列可以提供32字节块;其他128字节块等。每个阵列的位图管理分配

d) 我见过的最简单的实现完全忽略了
free()
(也就是说,
free()
是一个no-op),并在每个
malloc()
上分配池的下一部分


到目前为止,最常用的现代技术是a。变体b用于许多文件系统,如NTFS和FAT。选项c在许多DEC操作系统中受到青睐,尤其是在内核使用中。选项d由一些具有适当警告的极简嵌入式环境使用


在大多数实现中,请求的分配被四舍五入到某种自然倍数(通常为2、8、16等),以便于算法。因此,一系列5、3、8、7、4、1和15的分配可能都被视为一个16字节的请求。

是的,malloc有开销。这是完全特定于实现的。但一般来说,如果你的程序使用更少的大分配,而不是很多小分配,那么它的内存效率会更高。但是,在任何情况下,管理分配的内存都会有一些开销。您可以从以下位置开始阅读:可能重复的虽然问题基本相同,但答案在那里的阐述比在这里要少。值得注意的是,还有许多其他技巧可能需要额外的空间,例如使用特殊位模式填充以检测越界写入或有关分配的信息(代码的哪一部分进行了分配)用于调试目的。可能会添加一些内容。(顺便说一句:一个非常好的答案!)@chux:手册页中提到的乐观分配很有趣,但我不知道它是否合适。我想这意味着
sbrk()
是乐观的,可能会导致
malloc()
乐观,对吗?OP说“实际使用的内存空间实际上是10个单词?”思考
malloc()
和其他人也确实使用内存,而真正可能发生的事情是内存被标记为可用,但尚未使用,以及“额外内存”“当真正的使用发生时,可能会发生变化。如果这没有帮助,不要费心弄乱你的好答案。注意:乐观分配是与
sbrk()
不同的想法。当然。我简化了情况,因为思考
malloc
失败的情况并不真正适用于这个问题。