是否必须释放每个malloc调用

根据我的理解,因为malloc动态分配mem,你需要释放该mem以便它可以再次使用。

  1. 如果你返回一个使用malloc创建的char *会发生什么(即你应该如何释放它)
  2. 如果您将指针保持原样并退出应用程序将被释放。(我无法找到明确的答案,有些人说是,有些人说没有)。

  1. 呼叫者必须释放它(或安排它被释放)。 这意味着创建和返回资源的函数需要准确记录应该如何释放资源。

  2. 大多数操作系统将在程序退出时释放内存,作为“进程”定义的一部分。 C标准并不关心会发生什么,它超出了程序的范围。 并非所有操作系统都具有完整的流程抽象,但桌面式操作系统肯定会这样做。

在此之前释放它的主要原因是:

  • 如果您尽快释放内存,通常在进程退出前很长一段时间,您的程序总共使用较少的内存。
  • 如果你没有释放它,并且你以后想要将程序更改为另一个程序中的例程,这可能被多次调用,那么突然间你需要的内存比以前多很多(内存泄漏)。
  • 通过警告您在程序退出时仍然分配的内存,有一些调试工具可以帮助您识别内存泄漏。 如果有很多故意泄露的垃圾需要通过,这些并没有多大帮助。
  • 如果你没有释放它并且你遇到任何问题,那么以后回去并找到所有需要释放的内存要比在第一时间做到这一点要困难得多。
  • 在很多情况下你需要释放内存(以防止在长时间运行的程序中使用大量内存),你的默认策略必须是清理几乎所有东西。

不自由的含糊不清的理由是:

  • 更少的代码。
  • 如果在程序退出之前就有单独的块可以单独释放,那么让操作系统放弃整个过程可能要快得多。
  • 如果您不确切知道它的使用位置,那么按需创建并存储在全局中的东西可能很难安全地清理。 想想你在进行时填充的某种缓存,可能有MRU规则来限制它占用的内存量,因此它不是无限制的泄漏。 好的,所以这是一件坏事(不受限制的全局变量)导致另一件坏事(不同意的内存),但是值得了解为什么你可能会在现有代码中看到不一致的块,并且你不一定只是进去修复他们。

解放的原因几乎总是超过反对的原因。

  1. 如果你有一个指向malloc创建的malloc指针,那么使用该指针free该内存将会做正确的事情。 是的,有一些魔法涉及; 这将由您的编译器处理。

  2. 是的,如果忽略内存释放并退出应用程序,操作系统将释放内存。 然而,将其视为不一致被认为是不好的做法。 操作系统可能无法做正确的事情(特别是在嵌入式设置中),或者可能无法及时完成。 此外,如果您持续运行程序,最终可能会消耗越来越多的内存,最终消耗掉所有内存,并耗尽内存并导致崩溃。

是。 如果你是malloc,你需要免费。 如果您没有空闲,则在程序运行时保证内存泄漏。

释放它。

总是。

期。

如果您自己编写函数:避免这样做。

  • 相反,让调用者传递缓冲区,让调用者指定缓冲区的大小并将数据复制到该缓冲区中。 这样,您可以使用其他不使用相同堆的模块中的函数(其他编程语言,不同的C运行时…)
  • 如果由于某种原因无法使用这样的接口,请在函数文档中指定调用者在完成后必须释放返回的指针。

如果您使用的是库函数:请查看文档。

  • 如果文档说明您必须自由,请执行此操作。
  • 如果文档声明您没有必要,则可能需要调用一些全局清理函数来释放模块的资源。

关于你的第二个问题,建议在退出前释放。 从技术上讲,它不会受到伤害,但是当您想要在更大的项目中重用代码时,您会感谢您首先编写了正确的清理。

是的,每次调用malloc()都必须与对free()的调用相匹配。

回答您的具体问题:

  1. 您必须明确记录您的API,告诉用户返回的指针是否必须是free() ‘d
  2. 操作系统将释放分配给该进程的所有内存。

C标准没有单个程序执行之外的系统环境概念,因此它无法指定“程序退出后”发生的情况。 同时,在调用exit或从main返回之前,没有任何地方要求使用malloc获得的malloc应该或必须在释放之前释放,我认为很明显,目的是在没有手动释放内存的情况下退出不会让资源被束缚 – 就像在没有关闭所有文件的情况下调用exit自动关闭它们(包括刷新它们)。

现在,至于您是否应该 free拨打电话,这在很大程度上取决于您的特定节目。

  • 任何库代码都应该尽快free它纯粹供内部使用的任何内存。
  • 将分配的对象返回给调用程序的库应始终提供相应的调用以释放这些对象。
  • 作为全局初始化的一部分执行任何分配的库(注意:这是一个非常糟糕的设计,但有时是不可避免的)应该为应用程序提供一种方法来反转初始化并释放所分配的所有内容。 如果可能动态加载库(即使满足另一个动态加载的库的依赖项),这一点尤为重要。

到目前为止,我只讨论过库代码。 此时,剩下的就是应用程序本身或库代表应用程序进行的分配。 我的观点,我承认这是非正统的,释放这些物品不仅是不必要的,而且是有害的。 我说这个的主要原因是大多数长期存在的应用程序将积累相当多的分配内存,而这些内存并没有被大量使用(想想字处理器中的撤消缓冲区或浏览器中的历史记录)。 在适度加载的系统上,大部分数据在应用程序终止时已交换到磁盘。 如果你想要释放它,你将最终走遍所有已换掉的内存地址,追踪所有指向免费的指针,

  • 把无用的磨损放在硬盘的物理组件上
  • 让用户等待您的应用程序退出
  • 导致其他仍在使用的应用程序数据被换出,使它们运行得更慢

所有这一切都以一种荒谬的名义“你必须释放你所分配的一切”的规则。

对于短期应用程序来说,它并不是一件大事,但是你可以经常简化执行单个线性任务的短期应用程序的实现,如果你不打扰释放它们分配的所有内存,就可以退出。 想想大多数unix命令行实用程序。 是否有任何用于为sed编写循环以在退出之前释放所有已编译的正则表达式? 程序员的时间不能花在更有成效的事情上吗?

1)正常地释放内存的方式,即

 p = func(); //... free(p); 

诀窍是确保你总是这样做……

2)一般来说,是的。 但你仍然应该释放你使用的任何记忆作为良好的做法。 不花时间弄清楚在哪里释放内存只是懒惰。

让我们一次看一点……

  1. 如果你返回一个你知道是用malloc创建的char * ,那么是的,你有责任释放它。 你可以用free(myCharPtr)做到这free(myCharPtr)

  2. 操作系统将恢复内存,并且它不会永远丢失,但从技术上讲,无法保证在应用程序终止时它将被收回。 这只取决于操作系统。

我不会说每个malloc必须被释放,但我会说,无论程序运行多长时间,都必须有一定数量的分配(和总大小)不会被释放。 数字不一定是静态常量,但必须根据其他内容来指定(例如,此程序处理小部件;它将为最大小部件中的每个quizzix分配一个64字节结构)。 人们可能事先不知道最大小部件的大小,但是如果例如知道处理小部件所需的临时存储与其大小的平方成比例,则可以安全地推断出最大的小部件将足够小以至于总大小。滞留的内存量非常小。