我们使用malloc()在C中动态分配内存,并且我们收到指向堆中位置的指针。 现在我们使用free()来释放内存,传递与argumnet相同的指针值。
现在的问题是free()如何知道取消分配多少...考虑到我们总是可以调整malloc()分配的内存块的事实。
这里有与哈希表相关的内容吗?
答案 0 :(得分:5)
典型的实现将在malloc返回的地址之前存储信息。该信息将包括重新分配或免费需要知道的信息以进行其工作,但具体存储的详细信息取决于实施。
答案 1 :(得分:4)
最初的技术是分配一个稍大的块并在开头存储大小,这是应用程序没有看到的部分。额外的空间包含一个大小,并且可能链接到将空闲块连接在一起以便重复使用。
然而,这些技巧存在某些问题,例如缓存和内存管理行为不佳。在块中使用内存往往会不必要地对页面进行分页,并且还会创建脏页面,这会使共享和写时复制变得复杂。
因此,更高级的技术是保留一个单独的目录。还开发了外来方法,其中存储区域使用相同的两种功率。
一般来说,答案是:分配一个单独的数据结构来保持状态。
答案 2 :(得分:2)
简化的实现是着名的K&R C Bible,第186-188页。
我们实际获得的内存块比我们申请的更多(结构头部或联合头部的大小)。结构可能是这样的:
typedef long Align;
union header
{
struct
{
union header* ptr; // next block
unsigned size; // size of this block , times of head size
}s;
Align x;
};
一个证明它的图:
当我们调用free
函数时,行为可能是这样的:
void free(void* ptr)
{
Header *bp, *p;
bp = (Header *)ptr - 1;
/* ..... */
/*return the memory to the linked list */
}
在visual studio中,我们有两个模型:release version
和debug version
,我们甚至可以使用
头部存储调试消息以使调试更容易。debug version
中的标题称为_CrtMemBlockHeader
,定义如下:
typedef struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader * pBlockHeaderNext;
struct _CrtMemBlockHeader * pBlockHeaderPrev;
char * szFileName;
int nLine;
size_t nDataSize;
int nBlockUse;
long lRequest;
unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;
然后记忆lalout是:
答案 3 :(得分:1)
内存管理器使用表来存储基于指针的附加数据,有时在指针之前,有时在其他地方。 C非常简单,数据很可能是pointer-2
或pointer-4
,int
或long
类型。正确的细节取决于编译器。
答案 4 :(得分:1)
当我们使用malloc时,一个块将获得保留,其大小将比我们请求的更多,并且为了返回这个malloc,我们得到一个指向该块的开始的指针。 我告诉你这个块的大小将比你需要的更多。这个额外的空间将用于保持实际请求的块大小,指向下一个空闲块的指针以及一些检查“如果你试图访问多于分配块“。
因此,每当我们使用我们想要解除分配的指针调用free时,这个free将搜索块空间中给出的额外信息,它将获得最终大小以解除分配。