我想知道malloc和free是怎么工作的。
int main() {
unsigned char *p = (unsigned char*)malloc(4*sizeof(unsigned char));
memset(p,0,4);
strcpy((char*)p,"abcdabcd"); // **deliberately storing 8bytes**
cout << p;
free(p); // Obvious Crash, but I need how it works and why crash.
cout << p;
return 0;
}
如果答案是在记忆层面上的深度,如果可能的话,我会非常感激。
How malloc() and free() works depends on the runtime library used. Generally, malloc() allocates a heap (a block of memory) from the operating system. Each request to malloc() then allocates a small chunk of this memory be returning a pointer to the caller. The memory allocation routines will have to store some extra information about the block of memory allocated to be able to keep track of used and free memory on the heap. This information is often stored in a few bytes just before the pointer returned by malloc() and it can be a linked list of memory blocks.
通过写入超过malloc()分配的内存块,您很可能会破坏下一个块的一些簿记信息,这些信息可能是剩余的未使用的内存块。
在向缓冲区复制太多字符时,程序也可能崩溃。如果额外的字符位于堆之外,当您试图写入不存在的内存时,可能会遇到访问冲突。
How malloc() and free() works depends on the runtime library used. Generally, malloc() allocates a heap (a block of memory) from the operating system. Each request to malloc() then allocates a small chunk of this memory be returning a pointer to the caller. The memory allocation routines will have to store some extra information about the block of memory allocated to be able to keep track of used and free memory on the heap. This information is often stored in a few bytes just before the pointer returned by malloc() and it can be a linked list of memory blocks.
通过写入超过malloc()分配的内存块,您很可能会破坏下一个块的一些簿记信息,这些信息可能是剩余的未使用的内存块。
在向缓冲区复制太多字符时,程序也可能崩溃。如果额外的字符位于堆之外,当您试图写入不存在的内存时,可能会遇到访问冲突。
正如aluser在这个论坛上说的:
Your process has a region of memory, from address x to address y,
called the heap. All your malloc'd data lives in this area. malloc()
keeps some data structure, let's say a list, of all the free chunks of
space in the heap. When you call malloc, it looks through the list for
a chunk that's big enough for you, returns a pointer to it, and
records the fact that it's not free any more as well as how big it is.
When you call free() with the same pointer, free() looks up how big
that chunk is and adds it back into the list of free chunks(). If you
call malloc() and it can't find any large enough chunk in the heap, it
uses the brk() syscall to grow the heap, i.e. increase address y and
cause all the addresses between the old y and the new y to be valid
memory. brk() must be a syscall; there is no way to do the same thing
entirely from userspace.
Malloc()依赖于系统/编译器,所以很难给出一个具体的答案。基本上,它会跟踪它所分配的内存,这取决于它是如何做的,所以你对free的调用可能失败或成功。
malloc()和free()并不是在每个O/S上都以相同的方式工作。
您的strcpy行尝试存储9个字节,而不是8个字节,因为有NUL结束符。它调用未定义的行为。
The call to free may or may not crash. The memory "after" the 4 bytes of your allocation might be used for something else by your C or C++ implementation. If it is used for something else, then scribbling all over it will cause that "something else" to go wrong, but if it isn't used for anything else, then you could happen to get away with it. "Getting away with it" might sound good, but is actually bad, since it means your code will appear to run OK, but on a future run you might not get away with it.
使用调试风格的内存分配器,您可能会发现在那里写了一个特殊的保护值,free会检查该值,如果没有找到它就会惊慌失措。
否则,您可能会发现接下来的5个字节包括属于某个尚未分配的其他内存块的链接节点的一部分。释放块很可能涉及将其添加到可用块的列表中,并且由于您在列表节点中乱写了代码,该操作可能会解除对具有无效值的指针的引用,从而导致崩溃。
这完全取决于内存分配器——不同的实现使用不同的机制。