是否有其他方法可以释放 C 中动态分配的内存 - 不使用 free() 函数?

2024-05-14

我正在为测试而学习,我想知道这些是否等同于 free(ptr):

 malloc(NULL); 

 calloc(ptr); 

 realloc(NULL, ptr); 

 calloc(ptr, 0); 

 realloc(ptr, 0);

据我了解,这些都不起作用,因为 free() 函数实际上告诉 C ptr 之后的内存可以再次使用。抱歉,这是一个菜鸟问题,但我们将不胜感激。


实际上,最后一个相当于调用free()。阅读规格realloc()非常仔细,您会发现它可以重新分配数据,或者更改分配的大小(特别是如果新大小大于旧大小,可能会移动数据),并且它也可以释放内存。事实上,您不需要其他功能;它们都可以写成realloc()。并不是任何心智正常的人都会这样做……但这是可以做到的。

参见史蒂夫·马奎尔的“编写可靠的代码 https://rads.stackoverflow.com/amzn/click/com/1556155514“为了彻底剖析malloc()函数族。请参阅ACCU http://accu.org/网站对阅读“编写扎实的代码”的危险进行了完整剖析。我不相信它像评论中所说的那么糟糕 - 尽管它完全缺乏治疗const它确实有日期(可以追溯到 90 年代初,当时 C89 还很新,尚未广泛全面实施)。


D McKee 关于 MacOS X 10.5 (BSD) 的笔记很有趣......

C99标准说:

7.20.3.3 malloc 函数

Synopsis

#include <stdlib.h>
void *malloc(size_t size);

描述

malloc 函数为大小由 size 和 指定的对象分配空间 其值是不确定的。

Returns

malloc 函数返回空指针或指向已分配空间的指针。

7.20.3.4 realloc 函数

Synopsis

#include <stdlib.h>
void *realloc(void *ptr, size_t size);

描述

realloc 函数释放 ptr 指向的旧对象并返回一个 指向具有 size 指定大小的新对象的指针。新内容 对象应与释放之前的旧对象相同,最多为新旧大小中的较小者。新对象中超出旧对象大小的任何字节都具有不确定的值。

如果 ptr 是空指针,则 realloc 函数的行为类似于 malloc 函数 指定尺寸。否则,如果 ptr 与之前返回的指针不匹配 calloc、malloc 或 realloc 函数,或者空间已通过调用释放 对于 free 或 realloc 函数,行为是未定义的。如果记忆是新的 对象无法分配,旧对象不会被释放,并且它的值不会改变。

Returns

realloc 函数返回一个指向新对象的指针(该对象可能具有相同的属性) 值作为指向旧对象的指针),或者如果新对象无法被调用则为空指针 分配。


除了因额外标头和函数而进行的编辑性更改外,ISO/IEC 9899:2011 标准与 C99 的表述相同,但在第 7.22.3 节中而不是在第 7.20.3 节中。


realloc 的 Solaris 10 (SPARC) 手册页显示:

realloc() 函数将 ptr 的块指针的大小更改为 size 字节,并返回指向(可能移动的)块的指针。内容将保持不变,直至新旧尺寸中较小的一个。如果块的新大小需要块的移动,则释放块的先前实例化的空间。如果新大小更大,则未指定块的新分配部分的内容。如果 ptr 为 NULL,对于指定的大小,realloc() 的行为类似于 malloc()。如果 size 为 0 并且 ptr 不是空指针,则释放指向的空间。

这是一个非常明确的“它像 free() 一样工作”的声明。

然而,MacOS X 10.5 或 BSD 的说法有所不同,这再次证实了我第一段中“没有人头脑正常”的部分。


当然,还有C99 基本原理 http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf...它说:

7.20.3 内存管理函数

这些定义中对空指针和零长度分配请求的处理 功能部分是由支持这种范式的愿望引导的:

OBJ * p; // pointer to a variable list of OBJs
    /* initial allocation */
p = (OBJ *) calloc(0, sizeof(OBJ));
     /* ... */
     /* reallocations until size settles */
 while(1) {
    p = (OBJ *) realloc((void *)p, c * sizeof(OBJ));
         /* change value of c or break out of loop */
 }

据报道,这种编码风格不一定得到委员会的认可,但已广泛使用 使用。

某些实现已针对零字节的分配请求返回非空值。 尽管这种策略在理论上具有区分“无”和“零”(未分配的指针与指向零长度空间的指针)的优势,但它具有更引人注目的优势 需要零长度对象概念的理论上的缺点。由于此类物体 无法声明,它们存在的唯一方式就是通过这样的方式 分配请求。

C89 委员会决定不接受零长度对象的想法。分配情况 因此,函数可能会针对零字节的分配请求返回空指针。请注意,这种处理并不排除上面概述的范例。

C89 悄然发生变化

依赖于大小为零的分配请求的程序返回非空指针 会有不同的行为。

[...]

7.20.3.4 realloc 函数

第一个参数为空是允许的。如果第一个参数不为空,并且第二个参数为 0,则调用将释放第一个参数指向的内存,并且空参数可以是 回; C99 与不允许零大小对象的政策是一致的。

C99的一个新特性:realloc 函数已更改,以明确指向的 对象被释放,分配一个新对象,新对象的内容与 旧物体的尺寸,最多为两个尺寸中较小的一个。 C89 尝试指定新对象与旧对象是同一对象,但可能具有不同的地址。这冲突了 标准的其他部分假设对象的地址在其运行期间是恒定的 寿命。此外,当大小为零时支持实际分配的实现不支持 对于这种情况,必须返回一个空指针。 C89 似乎需要 null 返回值,并且 委员会认为这限制太多。


托马斯·帕德隆-麦卡锡 https://stackoverflow.com/users/15727/thomas-padron-mccarthy observed https://stackoverflow.com/questions/750060/is-there-an-alternative-way-to-free-dynamically-allocated-memory-in-c-not-usin/750075?noredirect=1#comment561534_750075:

C89 明确表示:“如果 size 为零且 ptr 不是空指针,则释放它指向的对象。”那么他们似乎在C99中删除了这句话?

是的,他们删除了该句子,因为它包含在开头句子中:

realloc函数释放ptr指向的旧对象

那里没有回旋的余地;旧对象被释放。如果请求的大小为零,那么您将返回任何内容malloc(0)可能会返回,通常(通常)是一个空指针,但也可能是一个非空指针,也可以返回到free()但不能合法地取消引用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否有其他方法可以释放 C 中动态分配的内存 - 不使用 free() 函数? 的相关文章

  • 格式说明符%02x

    我有一个简单的程序 include
  • 静态构造函数和 BeforeFieldInit?

    如果类型没有静态构造函数 则将执行字段初始值设定项 就在使用该类型之前 或者在某个时间点突发奇想 运行时 为什么这段代码 void Main start Dump Test EchoAndReturn Hello end Dump clas
  • 使用 ADAL v3 使用 ClientID 对 Dynamics 365 进行身份验证

    我正在尝试对我们的在线 Dynamics CRM 进行身份验证以使用可用的 API 我能找到的唯一关于执行此操作的官方文档是 https learn microsoft com en us dynamics365 customer enga
  • 是否可以使用 http url 作为 DirectShow .Net 中源过滤器的源位置?

    我正在使用 DirectShow Net 库创建一个过滤器图 该过滤器图通过使用 http 地址和 WM Asf Writer 来流式传输视频 然后 在网页上 我可以使用对象元素在 Windows Media Player 对象中呈现视频源
  • 在 Mono 中反序列化 JSON 数据

    使用 Monodroid 时 是否有一种简单的方法可以将简单的 JSON 字符串反序列化为 NET 对象 System Json 只提供序列化 不提供反序列化 我尝试过的各种第三方库都会导致 Mono Monodroid 出现问题 谢谢 f
  • Selenium - C# - Webdriver - 无法找到元素

    在 C 中使用 selenium 我试图打开浏览器 导航到 Google 并找到文本搜索字段 我尝试下面的 IWebDriver driver new InternetExplorerDriver C driver Navigate GoT
  • 2个对象,完全相同(除了命名空间)c#

    我正在使用第三方的一组网络服务 但遇到了一个小障碍 在我手动创建将每个属性从源复制到目标的方法之前 我想我应该在这里寻求更好的解决方案 我有 2 个对象 一个是 Customer CustomerParty 类型 另一个是 Appointm
  • 测量进程消耗的 CPU 时钟

    我用 C 语言编写了一个程序 它是作为研究结果创建的程序 我想计算程序消耗的确切 CPU 周期 精确的循环次数 知道我怎样才能找到它吗 The valgrind tool cachegrind valgrind tool cachegrin
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • 让网络摄像头在 OpenCV 中工作

    我正在尝试让我的网络摄像头在 Windows 7 64 位中的 OpenCV 版本 2 2 中捕获视频 但是 我遇到了一些困难 OpenCV 附带的示例二进制文件都无法检测到我的网络摄像头 最近我发现这篇文章表明答案在于重新编译一个文件 o
  • SQLAPI++ 的免费替代品? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何免费 也许是开源 的替代品SQLAPI http www sqlapi com 这个库看起来
  • .NET 和 Mono 之间的开发差异

    我正在研究 Mono 和 NET C 将来当项目开发时我们需要在 Linux 服务器上运行代码 此时我一直在研究 ASP NET MVC 和 Mono 我运行 Ubuntu 发行版 想要开发 Web 应用程序 其他一些开发人员使用 Wind
  • 以编程方式创建 Blob 存储容器

    我有一个要求 即在创建公司时 在我的 storageaccount 中创建关联的 blob 存储容器 并将容器名称设置为传入的字符串变量 我已尝试以下操作 public void AddCompanyStorage string subDo
  • 调用 .ToArray() 时出现 ArgumentException

    我有一个经常被清除的列表 代码完全是这样的 VisitorAgent toPersist List
  • 如何编写一个接受 int 或 float 的 C 函数?

    我想用 C 语言创建一个扩展 Python 的函数 该函数可以接受 float 或 int 类型的输入 所以基本上 我想要f 5 and f 5 5 成为可接受的输入 我认为我不能使用if PyArg ParseTuple args i v
  • 在 C# 的 WebAPI 中的 ApiController 上使用“传输编码:分块”提供数据

    我需要服务分块传输使用编码数据API控制器 因为我无权访问HttpContext or the Http请求 我有点不知道在哪里写入响应以及在哪里刷新它 设置如下 public class MyController ApiControlle
  • 如何从 Windows Phone 7 模拟器获取数据

    我有一个 WP7 的单元测试框架 它在手机上运行 结果相当难以阅读 因此我将它们写入 XDocument 我的问题是 如何才能将这个 XML 文件从手机上移到我的桌面上 以便我可以实际分析结果 到目前为止 我所做的是将 Debugger B
  • 任何人都可以清楚地告诉如何在不使用像 这样的预定义函数的情况下找到带有小数值或小数值的指数吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 例如 2 0 5 1 414 所以想要 我是 c 的新手 所以请解释简单的逻辑 如果不是复杂的逻辑也足够了 在数学中 从整数取幂到实数
  • 声明一个负长度的数组

    当创建负长度数组时 C 中会发生什么 例如 int n 35 int testArray n for int i 0 i lt 10 i testArray i i 1 这段代码将编译 并且启用 Wall 时不会出现警告 并且似乎您可以分配
  • 如何在 C# 中获取 CMD/控制台编码

    我需要指定正确的代码页来使用 zip 库打包文件 正如我所见 我需要指定控制台编码 在我的例子中为 866 C Users User gt mode Status for device CON Lines 300 Columns 130 K

随机推荐

  • 从 PowerShell 运行 SSIS 包,无需部署项目

    This https learn microsoft com en us sql integration services ssis quickstart run powershell view sql server ver16 ssis
  • 在 Ruby 中跨多个类实例记忆数据的好方法是什么?

    考虑 生成数据的对象的许多实例 如果每次运行只生成一次该数据 那就太好了 class HighOfNPeriods lt Indicator def generate data indicator data DataStream new 0
  • 有没有办法缓存 https 凭据以推送提交?

    我最近转而将我的存储库同步到 GitHub 上的 https 由于防火墙问题 并且每次都要求输入密码 有没有办法缓存凭据 而不是每次都进行身份验证git push 自 Git 1 7 9 2012 年发布 以来 Git 中有一个巧妙的机制可
  • PostgreSQL regexp_matches 只返回匹配的行?

    这是我第一次使用 regexp matches 我发现使用它只会返回与 SELECT 子句中的所有 regexp matches 匹配的行 例如 SELECT parameters regexp matches parameters a d
  • 角度订阅响应

    好吧 我对 Angular 还很陌生 所以我遇到了这个小问题 所以我遵循 Angular 指南 https angular io guide http https angular io guide http 所以我的问题是我的 http r
  • Java API 中单例类的示例

    Java API 中单例设计模式的最佳示例有哪些 是个Runtime类单例 我只想到两个例子 java lang Runtime getRuntime http java sun com javase 6 docs api java lan
  • 如何暂时暂停实时数据图表的绘制更新

    我想要 暂停 图表的系列更新来完成一些工作 就像我有一个按钮 当我单击它时 它将暂停图表更新 然后当我单击恢复按钮时 它将更新系列中的所有暂停点 我知道关于 chart1 Series SuspendUpdates 但它似乎不适合我 我使用
  • mysql jdbc 与 SSL 连接在 tls 握手级别失败

    我们的 mysql 服务器配置为仅接受与 ssl 密码 DHE RSA AES256 GCM SHA384 的连接 我正在使用 java mysql connector java 8 0 15 和 java 8 openjdk 版本 1 8
  • 如何使用递归字符串连接构建带有小计的 HTML 表?

    我有接下来的两张表 CREATE TABLE SalesByStore Brand VARCHAR 10 StoreName VARCHAR 50 Sales DECIMAL 10 2 CREATE TABLE SalesByBrand B
  • MySQL - 查询合并具有相同 id 的行并保留该 id 的所有条目但作为一条记录

    我一直在处理本地保存在 wamp 服务器上的 mysql 数据库中的表 我正在使用 wamp 中的 phpmyadmin 区域来运行查询 我正在尝试获取数据来执行以下操作 谁能帮我制作一张包含许多植物记录的表格 植物可以有多个名称 表格将其
  • 带有nearPoints()的动态ggplot图层闪亮

    我熟悉闪亮的基础知识 但在这里遇到了一些困难 我希望能够在单击某个点以突出显示该点时添加 ggplot 图层 我知道 ggvis 可以做到这一点 并且画廊中有一个很好的例子 但我希望能够使用nearPoints 捕获点击作为 ui 输入 我
  • 将 Xcode 4.5 新 XIB 文件恢复到 iOS<6

    我已经安装了Xcode 4 5 with iOS6 SDK以及其他用于测试目的的旧 SDK 从 4 3 到 6 0 很美 但是有一个BIG问题 生成一个新的 XIB 文件以兼容 iOS6 这是一个问题 因为我的应用程序需要运行在旧设备 不只
  • 不同事件的角度停止传播

    在我的 Angular 4 应用程序中 我有一个带有 dblclick 处理程序的父组件和一个带有 click 处理程序的子组件 组件 html
  • CPU Relax 指令和 C++11 原语

    我注意到许多使用特定于操作系统的原语实现的无锁算法 例如所描述的自旋锁here http locklessinc com articles locks 使用 Linux 特定的原子原语 经常使用 cpurelax 指令 使用 GCC 可以通
  • 数组匹配值过滤器 PHP [重复]

    这个问题在这里已经有答案了 我尝试在数组中搜索 但根本没有得到任何结果 假设我有一个包含一些值的数组 所以当我想搜索它们时 它总是返回 null 不知道为什么 假设这是我的数组 data Array 0 gt Array id gt 122
  • ASP.Net MVC 上的防伪系统

    当我输入以下代码时 using Html BeginForm LogOff Account FormMethod Post new id logoutForm Html AntiForgeryToken a href Log off a t
  • 如何通过iframe从父html传递参数?

    我有一个 html 页面 在其中以编程方式设置 iframe 的 src 如何通过 iframe src 传递参数并在子 html 中获取它们 下面是我的代码 function myFunction myIframe attr src my
  • 仅当所有记录都匹配时 SQL 连接

    我有3张桌子 CP carthead idOrder CP cartrows idOrder idCartRow CP shipping idCartRow idShipping dateShipped 每个 idOrder 可以有多个 i
  • 无法解析 JSON 文件中的 TAB

    我在加载 JSON 文件时遇到解析问题 这些文件似乎具有TAB他们身上的性格 当我去http jsonlint com http jsonlint com 然后我输入带有 TAB 字符的部分 My String Foo bar Bar fo
  • 是否有其他方法可以释放 C 中动态分配的内存 - 不使用 free() 函数?

    我正在为测试而学习 我想知道这些是否等同于 free ptr malloc NULL calloc ptr realloc NULL ptr calloc ptr 0 realloc ptr 0 据我了解 这些都不起作用 因为 free 函