在不释放旧内存的情况下重新分配 [英] realloc without freeing old memory

查看:51
本文介绍了在不释放旧内存的情况下重新分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to use realloc to increase memory size while keeping the pointer unchanged (because the callers uses it). realloc does not always do that; sometimes it returns a different pointer and frees the old one. I would like to "try" to realloc memory and if it is not possible, fallback to a different method using the original pointer - but realloc has already destroyed that!

如果不可能,是否有办法尝试增加malloc的内存而不破坏(就像realloc一样)旧指针?

Is there a way to try to increase malloc'ed memory without destroying (as realloc does) the old pointer if it is not possible?

例如

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

P.S.我不在乎可移植性(仅Linux,因此是标签).

P.S. I don't care about portability (linux only, thus the tag).

推荐答案

您应该查看所使用的libc中realloc()的源代码.从那里开始,应该很容易看到可以增加适当大小的路径,否则将返回一个新的指针.然后,使用该代码编写您自己的tryrealloc()函数.

You should take a look at the source code of realloc() from the libc you are using. From there, it should be easy to see the path followed when it can increase the size in place, and the else case where a new pointer will be returned instead. Then, use that to code your own tryrealloc() function.

例如,这是来自uclibc的realloc()源代码:

For example, this is the realloc() source code from uclibc : 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行,它在那里免费.

I have removed some parts for clarity. But you can see that at line 66, it check if it can simply increase the memory for the current pointer. This is the part you want to keep. The else case starting at line 69 is to handle the case where the old memory will be freed and a new pointer will be returned. This is the part you want to kick out and handle it differently. From what you are saying, I guess you will only want to remove line 77, where it does the free.

如果您采用这种方式,请记住,您将必须手动释放旧指针或新指针,因为两者现在都有效(并且您不希望发生内存泄漏).

If you go this way, remember that you will have to manually either free the old pointer or the new one, as both will now be valid (and you don't want a memory leak).

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

Also, this is for uclibc. If you are already using a different libc, you should base your new tryrealloc() function on the realloc() function of that libc.

编辑:如果使用此方法,则必须小心.您将基于内存管理器的内部解决方案,以便在各种libc实现之间以及同一libc的不同版本之间可以发生变化并且有所不同.因此,请牢记适当的注意和警告.

You must be careful if you use this approach. You will be basing your solution on the internals of the memory manager, so things can change and be different between the various libc implementations, but also between different versions of the same libc. So do that with the appropriate care and warning in mind.

这篇关于在不释放旧内存的情况下重新分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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