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++新的[]数组,这是另一回事——对于那些,知道精确的数组大小对于数组销毁是正确的。不过,没有这样的例子