c++ - 重新分配而不释放旧内存

标签 c++ c linux gcc realloc

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

有没有办法在不可能的情况下尝试增加 malloc 的内存而不破坏(如 realloc 所做的那样)旧指针?

例如

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 行,它检查是否可以简单地增加当前指针的内存。这是您要保留的部分。从第 69 行开始的 else 情况是处理旧内存将被释放并返回新指针的情况。这是您要踢出并以不同方式处理的部分。从你所说的来看,我猜你只想删除第 77 行,它是免费的。

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

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

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

关于c++ - 重新分配而不释放旧内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13936669/

相关文章:

C++ 名称查找 - 标准中的示例

c++ - 如何删除Qt窗口的所有 child ?

linux - 硬链接(hard link)不会在 docker 容器中创建,即使它们与主机位于同一文件系统中

linux - C-<SPC> 只是插入一个空格 emacs - tty 控制台

c++ - 取消libcurl easy handle

c++ - DLL导入/导出

c - 如何使用 C 在 Ubuntu 上获取 WIFI 参数(带宽、延迟)

c - 如何设置指向结构的 Gtk gpointer?

c - 如何在C中填充一个trie树?

linux - 如何为maven设置路径