GetMem允许您分配任意大小的缓冲区。在某个地方,大小信息由内存管理器保留,因为当您将指针传递给FreeMem时,您不需要告诉它缓冲区有多大。
该信息是否仅供内部使用,或者是否有办法检索指针所指向的缓冲区的大小?
发布于 2009-08-23 13:23:35
似乎GetMem()返回的指针所引用的块的大小必须可以从某个地方获得,因为FreeMem()不要求您确定要释放的内存大小-系统必须能够确定这一点,那么应用程序开发人员为什么不能确定呢?
但是,正如其他人所说,所涉及的内存管理的确切细节并不是由系统本身定义的……Delphi一直有一个可替换的内存管理器架构,并且为兼容内存管理器定义的“接口”不要求它们为任意指针提供此信息。
默认内存管理器将以任何适合它的方式维护必要的信息,但其他内存管理器几乎肯定会使用完全不同的,如果表面上相似的机制,所以即使你基于对一个内存管理器的深入了解而破解了一个解决方案,如果你改变了内存管理器(或者如果你改变了内存管理器,例如你可能默认使用的系统定义的内存管理器,例如,发生在Delphi 2005和2006之间),那么你的解决方案几乎肯定会崩溃。
一般来说,假定应用程序已经知道GetMem()分配的指针所引用的内存有多大,这对于RTL/内存管理器来说并不是一个不合理的假设,因为应用程序首先请求它!:)
如果你的应用程序没有分配指针,那么你的应用程序的内存管理器绝对无法知道它引用的块有多大。例如,它可能是指向某个较大块中间的指针--只有指针的源才可能知道它与它引用的内存之间的关系!
但是,如果您的应用程序确实需要维护有关其自身指针的此类信息,那么它当然可以很容易地通过一个简单的单例类或函数库来实现这一点,通过这些类或函数库来路由GetMem()/FreeMem()请求,以便为每个当前分配的指针维护相关请求大小的记录。这样的机制当然可以很容易地根据需要公开这些信息,完全可靠且独立于正在使用的任何内存管理器。
如果需要“准确的”记录,这实际上可能是唯一的选择,因为给定的存储器管理器实现可以为给定大小的数据分配比实际请求的更大的存储器块。我不知道是否有内存管理器确实做到了这一点,但为了提高效率,理论上它可以做到这一点。
发布于 2009-08-23 12:01:28
它是供内部使用的,因为它取决于所使用的MemoryManager。顺便说一句,这就是为什么你需要使用同一个MemoryManager中的GetMem/FreeMem对;没有标准的方法来知道内存是如何被保留的。
在Delphi语言中,如果您查看FastMM4,您可以看到内存是以小、中或大块的形式分配的:
小数据块分配在固定大小的数据块池中(数据块大小在数据块类型中的池级别定义)
TSmallBlockType = packed record
{True = Block type is locked}
BlockTypeLocked: Boolean;
{Bitmap indicating which of the first 8 medium block groups contain blocks
of a suitable size for a block pool.}
AllowedGroupsForBlockPoolBitmap: byte;
{The block size for this block type}
BlockSize: Word;
中数据块也以池的形式分配,但大小可变
{Medium block layout:
Offset: -8 = Previous Block Size (only if the previous block is free)
Offset: -4 = This block size and flags
Offset: 0 = User data / Previous Free Block (if this block is free)
Offset: 4 = Next Free Block (if this block is free)
Offset: BlockSize - 8 = Size of this block (if this block is free)
Offset: BlockSize - 4 = Size of the next block and flags
{Get the block header}
LBlockHeader := PCardinal(Cardinal(APointer) - BlockHeaderSize)^;
{Get the medium block size}
LBlockSize := LBlockHeader and DropMediumAndLargeFlagsMask;
大数据块按所需大小单独分配
TLargeBlockHeader = packed record
{Points to the previous and next large blocks. This circular linked
list is used to track memory leaks on program shutdown.}
PreviousLargeBlockHeader: PLargeBlockHeader;
NextLargeBlockHeader: PLargeBlockHeader;
{The user allocated size of the Large block}
UserAllocatedSize: Cardinal;
{The size of this block plus the flags}
BlockSizeAndFlags: Cardinal;
end;
发布于 2009-08-23 11:07:37
是仅供内部使用的信息,还是有办法检索指针所指向的缓冲区的大小?
这两个“选择”是否相互矛盾?
它仅供内部使用。
https://stackoverflow.com/questions/1319273
复制相似问题