简体   繁体   English

C++ 运行时动态内存大小

[英]C++ Size Of Dynamic Memory at Runtime

This is something I've been wondering for a while and never found an answer for:这是我一直想知道的事情,但从未找到答案:

Why is it that when you allocate something on the heap you cannot determine the size of it from just the pointer, yet you can delete it using just the pointer and somehow C++ knows how many bytes to free?为什么当你在堆上分配一些东西时,你不能只从指针确定它的大小,但你可以只使用指针来删除它,而 C++ 不知何故知道要释放多少字节?

Does this have something to do with the way it is stored on the heap?这与它在堆上的存储方式有关吗? Is this information there but not exposed by C++?这些信息是否存在但未由 C++ 公开?

And perhaps this should be a separate question but I think it's pretty related so I'll ask it here:也许这应该是一个单独的问题,但我认为它非常相关,所以我会在这里问:

Why is it a dynamic array of elements must be deleted using delete [] as opposed to just the simple delete command;为什么必须使用delete []而不是简单的delete命令来delete []元素的动态数组; why does C++ need this additional information to correctly free all the memory?为什么 C++ 需要这些附加信息才能正确释放所有内存?

When an allocation is made, a small section of memory immediately before [or, technically, somewhere completely different, but just before is the most common scenario] will store the size of the allocation, and in the case of new [] also store the number of allocated objects.进行分配时,紧接在 [或者,从技术上讲,完全不同的地方,但就在之前是最常见的情况] 之前的一小部分内存将存储分配的大小,并且在new []的情况下,还存储分配的对象数。

Note that the C++ standard doesn't give any way to retrieve this information for a reason: It may not accurately describe what is allocated, for example the size of an array may very well be rounded up to some "nice" boundary [almost all modern allocators round to 16 bytes at the very least, so that the memory is usable for SSE and other similar SIMD implementations on other processor architectures].请注意,C++ 标准没有提供任何方法来检索此信息,原因如下:它可能无法准确描述分配的内容,例如数组的大小很可能会四舍五入到某个“不错”的边界 [几乎所有现代分配器至少四舍五入到 16 个字节,以便内存可用于 SSE 和其他处理器架构上的其他类似 SIMD 实现]。 So if you allocated 40 bytes, it would report back 48, which isn't what you asked for, so it would be rather confusing.因此,如果您分配了 40 个字节,它会返回 48 个字节,这不是您要求的,因此会相当混乱。 And of course, there is no guarantee that the information is stored at ALL - it may be implied by some other information that is stored in the "admin" block of the allocation.当然,不能保证信息完全被存储——它可能被存储在分配的“管理”块中的一些其他信息所暗示。

And of course, you can use placement new , in which case there is no admin block, and the allocation is not deleted in the normal fashion - some arbitrary code wouldn't be able to tell the difference.当然,您可以使用placement new ,在这种情况下没有管理块,并且不会以正常方式删除分配 - 一些任意代码将无法区分。

delete differs from delete [] in that delete [] will know how many objects have been allocated, and call the destructor for all of those objects. deletedelete []不同之处在于delete []会知道已经分配了多少对象,并为所有这些对象调用析构函数。 It is also possible [or even likely] that new [] stores the number of elements in a way that means that calling delete [] on something that wasn't created with new [] will go horribly wrong.也有可能[甚至可能] new []以某种方式存储元素数量,这意味着在不是用new []创建的东西上调用delete [] new []会出现可怕的错误。

And as Zan Lynx commented, that if there is no destructor for the objects (eg when you are allocating data for int or struct { int x; double y; } , etc - including classes that don't have a constructor [note however that if you have another class inside the class, the compiler will build a destructor for you]), then there is no need to store the count, or do anything else, so the compiler CAN, if it wishes, optimise this sort of allocation into regular new and delete .正如 Zan Lynx 评论的那样,如果对象没有析构函数(例如,当您为intstruct { int x; double y; }分配数据时 - 包括没有构造函数的类 [注意但是如果您在类中有另一个类,编译器将为您构建一个析构函数]),那么就不需要存储计数或做任何其他事情,因此编译器可以,如果愿意,可以将这种分配优化为常规newdelete

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM