调用
free()
来释放由malloc()
函数调用分配的内存。 free()
从哪里找到关于否的信息。由malloc()
函数分配的字节数。即,你如何遵守诺言。由malloc()
分配的字节数,以及存储此信息的位置。
-Surya
答案 0 :(得分:8)
C内存分配函数的大多数实现都将内联或单独存储每个块的记帐信息。
一种典型的方式(内联)是实际分配标题和你要求的内存,填充到某个最小尺寸。例如,如果您要求20个字节,系统可能会分配一个48字节的块:
然后给你的地址是数据区的地址。然后,当您释放该块时,free
将简单地获取您提供的地址,并假设您没有填写该地址或其周围的内存,请检查它之前的会计信息。
请记住标头的大小和填充是完全实现定义的(实际上,整个过程是实现定义的 a ,但是inline-accounting-info选项是常见的)。
如果您覆盖会计信息中存在的校验和和特殊标记通常是“内存竞技场已损坏”等错误的原因。填充(为了提高分配效率)是为什么你有时可以在你所请求空间的末尾写一点而不会引起问题(仍然,不要这样做,它是未定义的行为,只是因为它有时有效,不会'这意味着可以这样做。)
a 我在嵌入式系统中编写了malloc
的实现,无论你要求什么(这是系统中最大结构的大小),你都得到128字节一个简单的非内联位掩码用于决定是否分配了一个128字节的块。
我开发的其他人有16个字节的块,64个字节的块,256个字节的块和1K个块的不同池,再次使用位掩码来减少会计信息的开销并提高{{的速度1}}和malloc
(不需要合并相邻的空闲块),在我们工作的环境中尤为重要。
答案 1 :(得分:3)
这取决于实现。堆以某种方式存储该数据,这有助于访问具有malloc()
返回的指针的数据 - 例如,块可以在开头存储字节数,malloc()
将返回偏移指针。 / p>
答案 2 :(得分:2)
分配内存块时,会分配比您请求的字节数更多的字节。有多少取决于实现,但这是一个例子:
struct MallocHeader {
struct MallocHeader * prev, * next;
size_t length;
... more data, padding, etc ...
char data[0];
}
当malloc()
从空闲列表中分配内存时,它将分配size + sizeof(struct MallocHeader)
并返回data
的地址。在free()
中,从您传入的指针中减去结构data
中MallocHeader
的偏移量,然后它知道大小。
答案 3 :(得分:0)
这取决于实现 - 它取决于libc实现以及操作系统实现(更多关于操作系统实现)。
我没有必要知道这些事情,但如果你真的想要,你可以创建自己的memory allocator。
我错误地发现,在使用 new [] 运算符分配时,在C ++中存储分配区域开头的元素数量,将区域返回给用户>元素数量(在Visual Studio上)。
new[NUMBER] ---> [NUMBER (4bytes)]+[allocated area]
it returns the pointer to the allocated area
and probably when the delete[] operator is called
it looks 4 bytes before the [allocated area] to see
how much elements will be deleted