重新分配而不释放旧内存

2023-11-24

我想使用 realloc 来增加内存大小,同时保持指针不变(因为调用者使用它)。 realloc 并不总是这样做;有时它会返回一个不同的指针并释放旧的指针。我想“尝试”重新分配内存,如果不可能,则使用原始指针回退到不同的方法 - 但重新分配已经破坏了它!

如果不可能的话,有没有办法尝试增加 malloc 的内存而不破坏(如 realloc 那样)旧指针?

E.g.

void *pold;
void *pnew = realloc(pold, newsize);
if (pnew != pold)
{
     free(pnew);
     DoDifferently(pold); // but pold is freed already
}

附:我不关心可移植性(仅限Linux,因此是标签)。


您应该从您正在使用的 libc 中查看 realloc() 的源代码。从那里,应该很容易看到当它可以增加适当大小时遵循的路径,以及否则将返回新指针的情况。然后,使用它来编写您自己的 tryrealloc() 函数。

例如,这是来自 uclibc 的 realloc() 源代码:http://cristi.indefero.net/p/uClibc-cristi/source/tree/nptl/libc/stdlib/malloc/realloc.c

24  void *
25  realloc (void *mem, size_t new_size)
26  {
...
57    if (new_size > size)
58    /* Grow the block.  */
59    {
60        size_t extra = new_size - size;
61  
62        __heap_lock (&__malloc_heap_lock);
63        extra = __heap_alloc_at (&__malloc_heap, base_mem + size, extra);
64        __heap_unlock (&__malloc_heap_lock);
65  
66        if (extra)
67          /* Record the changed size.  */
68          MALLOC_SET_SIZE (base_mem, size + extra);
69        else
70          /* Our attempts to extend MEM in place failed, just
71             allocate-and-copy.  */
72        {
73          void *new_mem = malloc (new_size - MALLOC_HEADER_SIZE);
74          if (new_mem)
75            {
76              memcpy (new_mem, mem, size - MALLOC_HEADER_SIZE);
77              free (mem);
78            }
79          mem = new_mem;
80        }
81      }
...

为了清楚起见,我删除了一些部件。但您可以看到,在第 66 行,它检查是否可以简单地增加当前指针的内存。这是您要保留的部分。这else从第69行开始的情况是处理旧内存将被释放并返回新指针的情况。这是您想要踢出并以不同方式处理的部分。根据你所说的,我猜你只想删除第 77 行,它在其中执行 free。

如果您这样做,请记住您将必须手动释放旧指针或新指针,因为两者现在都有效(并且您不希望内存泄漏)。

另外,这是针对 uclibc 的。如果您已经在使用不同的 libc,则应该基于新的 libctryrealloc()函数在realloc()该libc的函数。

EDIT:如果您使用这种方法,您必须小心。您的解决方案将基于内存管理器的内部结构,因此在不同的 libc 实现之间以及同一 libc 的不同版本之间,情况可能会发生变化并有所不同。因此,请牢记适当的谨慎和警告。

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

重新分配而不释放旧内存 的相关文章

  • 使用 QTextCursor 选择一段文本

    使用 Qt 框架选择文本片段时遇到问题 例如 如果我有这个文件 没有时间休息 我想选择 ime for r 并从文档中删除这段文本 我应该如何使用 QTextCursor 来做到这一点 这是我的代码 QTextCursor cursor n
  • 导入错误:没有名为“tensorrt”的模块

    我使用 Debian 安装在我的虚拟机上安装了 TensorRT 如果我运行 dpkg l grep TensorRT 我会得到预期的结果 ii graphsurgeon tf 5 0 2 1 cuda10 0 amd64 GraphSur
  • 优化对绑定到 DataGridView 的 DataTable 的更新

    我的应用程序中有一个显示一些数据的表单 当我第一次显示表单时 我将一些数据加载到 DataTable 中 然后将 DataTable 绑定到 DataGridView 我还启动了一个异步方法来执行一些较慢的数据库查询 当这些慢查询完成时 我
  • CMake - 未定义参考

    我正在尝试将 gtest 包含到我的项目中 问题是我在 GTest 中收到未定义的引用错误 我正在尝试在 Gtest 中测试 Node 类 在节点的构造函数中 我使用类记录器 尽管我已将库记录器添加到 gtest target 中 但我仍然
  • 按位非运算符

    为什么要按位运算 0 打印 1 在二进制中 不是0应该是1 为什么 你实际上很接近 在二进制中 不是0应该是1 是的 当我们谈论一位时 这是绝对正确的 然而 一个int其值为0的实际上是32位全零 将所有 32 个 0 反转为 32 个 1
  • “volatile void function( ... )” 做了什么?

    我见过从语法角度来看 C 函数中 volatile 关键字有多少种用法 https stackoverflow com questions 7643528 how many usage does volatile keyword have
  • 没有真正理解 std::atomic::compare_exchange_weak 和compare_exchange_strong 的逻辑

    我读了https en cppreference com w cpp atomic atomic compare exchange https en cppreference com w cpp atomic atomic compare
  • 让 GCC/Clang 使用 CMOV

    我有一个简单的标记值联合 这些值可以是int64 ts or doubles 我正在对这些联合进行加法 但需要注意的是 如果两个参数都代表int64 t值 那么结果也应该有一个int64 t value 这是代码 include
  • Linux 内核中是否使用了扩展指令集(SSE、MMX)?

    好吧 它们带来 至少应该带来 性能的巨大提升 不是吗 所以 我还没有看到任何 Linux 内核源代码 但很想问 它们是否以某种方式被使用 在这种情况下 对于没有此类指令的系统 必须有一些特殊的 代码上限 SSE 和 MMX 指令集在音频 视
  • 适用于 Windows 的键值数据库?

    除了 MongoDB 和 Memcached 之外 Windows 上还运行哪些键值存储 我见过的大多数似乎只能在 Linux 上运行 Hypertable Redis Lightcloud 相关链接 是否有经过商业验证的云存储 Key g
  • 使用 for 循环创建链表

    这是我的结构 struct ListItem int data struct ListItem next 假设链表的第一个节点的 data 0 我想编写一个 for 循环来创建大小为 5 的链表 但我不知道如何工作 我尝试了以下方法 int
  • 复杂的 C 声明

    我刚刚在互联网上浏览了一些代码 发现了这个 float foo SIZE SIZE 我如何阅读这份声明 是否有一套特定的规则来阅读如此复杂的声明 我有一段时间没做这个了 从 开始foo然后向右走 float foo SIZE SIZE fo
  • C语言:如何获取使用strtok()一次后剩余的字符串

    我的字符串是 A B C D E 分隔符是 如何获取执行 strtok 一次后剩余的字符串 即 B C D E char a A B C D E char separator char b strtok a separator printf
  • C++ std:.auto_ptr 或 std::unique_ptr (支持多个编译器,甚至是旧的 C++03 编译器)?

    我正在尝试更新一些 C 代码 我想转向更现代的代码 c 11 但我仍然需要使用一些较旧的编译器 兼容 c 03 来编译代码 因为支持的平台限制 我知道在 C 11 编译器中 std auto ptr 已被弃用 但由于较旧的编译器支持 我不能
  • MPI_Gatherv:根数组中收到的垃圾值

    我正在尝试实施MPI Gatherv函数于C 根据我的程序 包括 root 在内的每个进程都应该创建一个大小等于 进程的等级 1 这将在所有单元格中保持进程的等级 然后这个本地数组被收集到根的 rcv array 中 不知何故 我得到了垃圾
  • 派生类的聚合初始化

    以下代码无法使用 Visual Studio2017 或在线 GDB 进行编译 我期望它能够编译 因为迭代器只是一个具有类型的类 并且它是从公共继承的 这是不允许的还是在 VS2017 中不起作用 template
  • 将函数作为函数参数传递

    Unity C 似乎无法识别Func lt gt 作为函数委托的符号 那么 如何将函数作为函数参数传递呢 我有一个想法Invoke functionName 0 可能有帮助 但我不确定它是否实际上立即调用该函数 或者等待帧结束 还有别的办法
  • 使用std::begin()、std::end()将ArrayXd转换为stl向量,

    在我看来我应该能够使用std begin and std end 转换ArrayXd to std vector
  • 序列化时如何跳过 xml 声明?

    我正在尝试输出一个没有 xml 头的 xml 文件 例如 我试过 Type t obj GetType XmlSerializer xs new XmlSerializer t XmlWriter xw XmlWriter Create c
  • C# 记录类型:记录子类之间的相等比较

    给定父记录类型 public record Foo string Value 和两个记录子类Bar and Bee我想知道是否可以实施Equals在基类中 因此 Foo Bar 或 Bee 的实例都被考虑equal基于Value 两者都与E

随机推荐

  • 如何在 Perl 6 中声明固定大小的本机数组?

    我试图在 Perl 6 中声明以下 C 结构 struct myStruct int A 2 lt NEED to declare this int B int C 我的问题是我不知道如何声明int A 2 部分使用内置的 NativeCa
  • Ionic2 - 每当我使用 navCtrl 推送新页面/组件时,选项卡就会消失

    根据我对 Ionic 文档和问题的理解 例如 推送新页面时如何保持tab 我已经正确完成了防止标签栏被隐藏所需的操作 需要明确的是 当导航在任何选项卡页上启动并且您转到堆栈中的任何其他选项卡页时 选项卡栏会正确显示 每当您从导航控制器或模态
  • 从 Spring 返回 Excel 可下载文件

    所以我有一个 Spring 控制器 我想创建一个 Excel 文件并返回它 以便浏览器下载它 我正在使用 JEXcelApi 这是我的控制器代码 RequestMapping value excel cols colString rows
  • 在 Delphi 中使用旧式“对象”而不是“类”有好处吗?

    在德尔福sane人们使用一个class来定义对象 在 Windows 版 Turbo Pascal 中我们使用object今天你仍然可以使用object创建一个对象 不同的是 一个object存在于堆栈中并且class存在于堆上 当然还有o
  • Java (JSP/Servlet):相当于 .jsp 中的 getServletContext()

    我应该如何从 jsp 访问 ServletContext 例如 我如何调用获取真实路径 jsp 内部的方法 这是一个 Servlet 它运行良好 protected void doGet HttpServletRequest req Htt
  • Eclipse Maven 插件配置问题

    我已关注这个线程 现在 当我尝试使用已安装的 Maven 插件进行构建时 出现以下错误 我执行的目标是clean X install Unable to locate the Javac Compiler in C Program File
  • 如何使用 LLVM 传递中的现有函数传递?

    我一直在使用 LLVM 但我很困惑如何使用与我自己的通行证不同的已存在通行证 准确地说 我的程序需要针对任何给定指令进行优势前沿计算 LLVM 已经具有作为函数传递实现的 Dominance 函数类 我如何在我的模块通行证中调用它 使用它
  • 有没有一种简单安全的方法将 PrintWriter 转换为 PrintStream?

    有没有一种干净简单的方法来转换实例java io PrintWriter into a java io PrintStream 首先获得一个OutputStream来自Writer See 这个问题 然后将其作为参数传递给PrintStre
  • R:在朋友组中最佳地共享 Cookie

    我正在使用 R 编程语言 假设有 100 人 每个人都用 1 100 开始的 ID 表示 每个人都可以与其他人成为朋友 数据集可以用图形 网络格式表示 如下所示 Set the seed for reproducibility set se
  • Selenium 作为 Windows 服务运行以获取错误屏幕截图

    我想要一个基于 Selenium RC 的自动化 Web 测试套件 以便在遇到某些错误时截取页面的屏幕截图 该测试套件是持续集成过程的一部分 从技术上讲 由作为运行的 CruiseControl 执行Windows服务 The seleni
  • JavaScript 写入文本文件

    我正在尝试从表单中获取输入并将其保存到与 html 文件位于同一文件夹中的文本文件中 这是我到目前为止所拥有的
  • Spring 3:如何从 TaskExecutor 调用 @Async 注解的方法

    我是 Spring 异步任务执行的新手 所以如果这听起来像一个愚蠢的问题 请原谅我 我读到 Async 注释是从 Spring 3 x 开始在方法级别引入的 该方法的调用将异步发生 我还读到我们可以在 spring 配置文件中配置 Thre
  • 如何使用 Perl 轻松批量重命名文件?

    我有很多文件正在尝试重命名 我尝试创建一个正则表达式来匹配它们 但即使如此 我仍然卡在文件的命名上 如下所示 文件名01 文件名 100 文件名02 文件名03 等等 我想在任何小于 100 的文件后面添加一个 0 零 如下所示 文件名00
  • JavaFX - 等待任务完成

    我有一个 JavaFX 应用程序 它实例化了几个Task对象 目前 我的实现 见下文 调用行为运行工厂 它在任务对象下执行计算 与此平行的是 下一个函数 被调用 有没有办法拥有下一个函数 等待 直到先前的任务完成 我明白线程 join 等待
  • 树莓派自动登录无需etc/inittab

    我想将我的 Raspberry Pi 设置为以特定用户自动登录 我用谷歌搜索了这个 我找到的解决方案是关于编辑 etc inittab 文件 我的问题是现在我没有该文件 它在我的 Raspbian 版本中似乎丢失了 还有其他方法可以做到这一
  • 相当于 X11 中的“无效矩形”/“WM_PAINT”

    我正在将一些代码从 Windows 移植到 XLib 在Windows代码中 我可以通过调用强制重绘InvalidateRect然后处理相应的WM PAINT信息 但是 我无法找到如何在 X11 XLib 中执行此操作 我看到有一个Expo
  • 使用 javascript 将内容添加到表格行 ()?

    我有一个表如下 table tr td col 1 td td col2 td tr tr td field td td Field 2 td tr tr td another field td td one more field td t
  • MySQL 从一张表更新到另一张表时条件不起作用?

    我尝试过一种似乎对其他人有效的解决方案 从表 b 更新表 a 其中 条件 我似乎无法让它工作 MySql 给了我一个语法错误 我有两个表 我需要将一个表中的一列更新为另一列的值 其中两个表中的 id 都匹配 UPDATE video dat
  • 找不到控制器方法 - laravel 4

    我在尝试运行任何控制器时收到此消息 Symfony Component HttpKernel Exception NotFoundHttpException 未找到控制器方法 我的路线文件中有此代码 Route controller Hom
  • 重新分配而不释放旧内存

    我想使用 realloc 来增加内存大小 同时保持指针不变 因为调用者使用它 realloc 并不总是这样做 有时它会返回一个不同的指针并释放旧的指针 我想 尝试 重新分配内存 如果不可能 则使用原始指针回退到不同的方法 但重新分配已经破坏