free 和 malloc 如何在 C 中工作? [英] How do free and malloc work in C?

查看:29
本文介绍了free 和 malloc 如何在 C 中工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想弄清楚如果我尝试从中间"释放一个指针会发生什么例如,看下面的代码:

I'm trying to figure out what would happened if I try to free a pointer "from the middle" for example, look at the following code:

char *ptr = (char*)malloc(10*sizeof(char));

for (char i=0 ; i<10 ; ++i)
{
    ptr[i] = i+10;
}
++ptr;
++ptr;
++ptr;
++ptr;
free(ptr);

我因未处理的异常错误消息而崩溃.我想了解免费为什么以及如何工作,这样我不仅知道如何使用它,而且还能够理解奇怪的错误和异常,并更好地调试我的代码.

I get a crash with an Unhandled exception error msg. I want to understand why and how free works so that I know not only how to use it but also be able to understand weird errors and exceptions and better debug my codeץ

非常感谢

推荐答案

当你 malloc 一个块时,它实际上分配的内存比你要求的多一点.这个额外的内存用于存储信息,例如已分配块的大小,到块链中下一个空闲/已用块的链接,有时还有一些保护数据",可帮助系统检测您是否写了过去分配块的结尾.此外,大多数分配器会将总大小和/或您的内存部分的开头四舍五入为字节的倍数(例如,在 64 位系统上,它可能会将数据对齐为 64 位(8 字节)的倍数,如从非对齐地址访问数据对于处理器/总线来说可能更加困难和低效),因此您最终可能还会得到一些填充"(未使用的字节).

When you malloc a block, it actually allocates a bit more memory than you asked for. This extra memory is used to store information such as the size of the allocated block, and a link to the next free/used block in a chain of blocks, and sometimes some "guard data" that helps the system to detect if you write past the end of your allocated block. Also, most allocators will round up the total size and/or the start of your part of the memory to a multiple of bytes (e.g. on a 64-bit system it may align the data to a multiple of 64 bits (8 bytes) as accessing data from non-aligned addresses can be more difficult and inefficient for the processor/bus), so you may also end up with some "padding" (unused bytes).

当您释放指针时,它使用该地址来查找它添加到您分配的块的开头(通常)的特殊信息.如果传入不同的地址,它将访问包含垃圾的内存,因此其行为未定义(但最常见的是会导致崩溃)

When you free your pointer, it uses that address to find the special information it added to the beginning (usually) of your allocated block. If you pass in a different address, it will access memory that contains garbage, and hence its behaviour is undefined (but most frequently will result in a crash)

稍后,如果您 free() 块但没有忘记"您的指针,您可能会在将来不小心尝试通过该指针访问数据,并且行为未定义.可能会出现以下任何一种情况:

Later, if you free() the block but don't "forget" your pointer, you may accidentally try to access data through that pointer in the future, and the behaviour is undefined. Any of the following situations might occur:

  • 内存可能被放在一个空闲块列表中,所以当你访问它时,它仍然包含你留在那里的数据,你的代码运行正常.
  • 内存分配器可能已将(部分)内存分配给程序的另一部分,然后可能会覆盖(部分)您的旧数据,因此当您读取它时,您会得到垃圾,这可能导致意外行为或代码崩溃.或者您将覆盖其他数据,导致程序的其他部分在未来的某个时刻表现异常.
  • 内存可能已返回给操作系统(您不再使用的内存页面"可以从您的地址空间中删除,因此该地址不再有任何可用内存 - 本质上是未使用的内存应用程序内存中的漏洞").当您的应用程序尝试访问数据时,会发生硬内存故障并终止您的进程.

这就是为什么在释放指针指向的内存后确保不使用指针很重要 - 最佳实践是在释放内存后将指针设置为 NULL,因为您可以轻松测试NULL,并尝试通过 NULL 指针访问内存会导致错误但一致的行为,这更容易调试.

This is why it is important to make sure you don't use a pointer after freeing the memory it points at - the best practice for this is to set the pointer to NULL after freeing the memory, because you can easily test for NULL, and attempting to access memory via a NULL pointer will cause a bad but consistent behaviour, which is much easier to debug.

这篇关于free 和 malloc 如何在 C 中工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆