Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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
Memory 程序如何知道要释放多少内存? 我怀疑我的问题的答案是语言特定的,所以我想知道C和C++。当我在缓冲区上调用free()或使用delete[]时,程序如何知道要释放多少内存_Memory_Implementation - Fatal编程技术网

Memory 程序如何知道要释放多少内存? 我怀疑我的问题的答案是语言特定的,所以我想知道C和C++。当我在缓冲区上调用free()或使用delete[]时,程序如何知道要释放多少内存

Memory 程序如何知道要释放多少内存? 我怀疑我的问题的答案是语言特定的,所以我想知道C和C++。当我在缓冲区上调用free()或使用delete[]时,程序如何知道要释放多少内存,memory,implementation,Memory,Implementation,缓冲区或动态分配数组的大小存储在哪里?为什么程序员不能使用它?每个实现都会有所不同,但通常运行时分配的比要求的稍多,并在块的开头使用一些隐藏字段来记住分配的大小。因此,返回给调用方的地址与从堆中声明的内存的起始位置偏移了一位 调用方无法使用它,因为从堆中声明的实际内存量是一个实现细节,并且在编译器和平台之间会有所不同。至于知道调用方请求了多少,而不是从堆中分配了多少。。。好的,语言设计者假设程序员能够在需要时记住这一点。每个实现都会有所不同,但通常运行时分配的比要求的多一点,并在块的开头使用一些

缓冲区或动态分配数组的大小存储在哪里?为什么程序员不能使用它?

每个实现都会有所不同,但通常运行时分配的比要求的稍多,并在块的开头使用一些隐藏字段来记住分配的大小。因此,返回给调用方的地址与从堆中声明的内存的起始位置偏移了一位


调用方无法使用它,因为从堆中声明的实际内存量是一个实现细节,并且在编译器和平台之间会有所不同。至于知道调用方请求了多少,而不是从堆中分配了多少。。。好的,语言设计者假设程序员能够在需要时记住这一点。

每个实现都会有所不同,但通常运行时分配的比要求的多一点,并在块的开头使用一些隐藏字段来记住分配的大小。因此,返回给调用方的地址与从堆中声明的内存的起始位置偏移了一位


调用方无法使用它,因为从堆中声明的实际内存量是一个实现细节,并且在编译器和平台之间会有所不同。至于知道调用方请求了多少,而不是从堆中分配了多少。。。好的,语言设计者假设程序员能够在需要时记住这一点。

它在内部存储在依赖于语言/编译器/操作系统的位置


有时它是可用的(例如,C#中的长度),但这可能只是指允许使用的内存量,而不是对象的总大小。

它内部存储在依赖于语言/编译器/操作系统的位置


有时它是可用的(例如(.Length in C#),但这可能只是指允许使用的内存量,而不是对象的总大小。

通常是因为要释放的大小存储在分配的缓冲区中的某个位置。一种常见的技术是将大小存储在返回指针之前的内存中


为什么程序员不能获得这些信息?我真的不知道。我猜这是因为一个实现可能能够提供内存分配,而实际上不需要存储它的大小,而且这种实现(如果存在的话)不应该受到其他实现的惩罚。

通常是因为要释放的大小存储在分配的缓冲区中的某个地方。一种常见的技术是将大小存储在返回指针之前的内存中


为什么程序员不能获得这些信息?我真的不知道。我猜这是因为一个实现可能能够提供内存分配,而不需要实际存储其大小,而且这种实现(如果存在的话)不应该受到其他实现的惩罚。

它不是那么特定于语言。这一切都是由内存管理器完成的


它如何知道取决于内存管理器如何管理内存。一般的想法是,内存管理器分配的内存比您要求的要多。它在这些位置存储有关已分配内存块的额外数据。因此,当您释放内存时,它会使用存储在这些位置的信息(根据给定的指针重新构造),并计算出需要停止管理的实际内存量。

它与语言无关。这一切都是由内存管理器完成的


它如何知道取决于内存管理器如何管理内存。一般的想法是,内存管理器分配的内存比您要求的要多。它在这些位置存储有关已分配内存块的额外数据。因此,当您释放内存时,它会使用存储在这些位置的信息(根据给定指针重建),并计算出要停止管理的实际内存量。

提供该内存块的内存分配器负责所有维护数据。通常它存储在块的开头(就在您使用的实际地址之前),因此在释放时很容易访问


关于你的另一个问题:为什么你的应用程序应该知道它?这不关你的事。它将内存分配管理与应用程序分离,因此您可以使用不同的分配器(出于性能或调试原因)。

提供该内存块的内存分配器负责所有维护数据。通常它存储在块的开头(就在您使用的实际地址之前),因此在释放时很容易访问


关于你的另一个问题:为什么你的应用程序应该知道它?这不关你的事。它将内存分配管理与应用程序分离,因此您可以使用不同的分配器(出于性能或调试原因)。

堆会跟踪所有内存块,包括已分配和空闲的内存块,专门用于此目的。典型的(如果幼稚的话)实现分配内存,在开始时使用几个字节进行簿记,并返回超过这些字节的地址。在后续操作(free/realloc)中,它将减去几个字节以到达簿记区域

一些堆实现(例如,Windows“
GlobalAlloc()
)让您知道给定起始地址的块大小。但是在C/C++RTL堆中,没有这样的服务

请注意,malloc()有时会过度分配内存,因此有关
malloc
ated块大小的信息用处有限。C++新的[]数组,这是另一回事——对于那些,知道精确的数组大小对于数组销毁是正确的。不过,没有这样的例子