【问题标题】:Realloc simply not diong anything, not erroringRealloc 根本不会做任何事情,不会出错
【发布时间】:2014-01-26 01:20:26
【问题描述】:

我有以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char ** argv)
{
    //just checking to see where the stack 
    printf("The stack is around %p\n", &argc); is, making sure arr isn't in it
    char ** arr = malloc(8*sizeof(char*));
    printf("arr is size %li, at %p\n", sizeof(arr), arr);
    arr = realloc(arr, 100); //I picked a weird number to show it isn't doing anything. I've picked different numbers (like 200, 2*sizeof(char*)*sizeof(arr), and 16)
    printf("arr is size %li, at %p\n", sizeof(arr), arr);
}

这是整个文件(这是一个单元测试;我在其他地方注意到了)

上面的输出如下:

The stack is around 0x7fff5b94d12c
arr is size 8, at 0x120f010
arr is size 8, at 0x120f010

也许我误解了 realloc 应该做什么。我期待以下输出。

The stack is around 0x7fff5b94d12c
arr is size 8, at 0x120f010
arr is size <size>, at <somewhere>

&lt;size&gt; 是...奇怪的值,例如 12...至少不是 8,&lt;somewhere&gt; 很可能是 0x120f010,但可能在任何合理的地方。

是我的期望错误还是我使用 realloc 不正确?

【问题讨论】:

  • 真正的问题是你误解了sizeof...
  • 你是对的,我是。谢谢...现在调试原程序。

标签: c malloc realloc


【解决方案1】:

你的程序的输出是正确的,因为

  • mallocrealloc 都与自动存储(即“堆栈”)无关。它们从动态存储区域(即“堆”)分配内存。不应期望堆栈顶部的位置会随着对 mallocrealloc 或任何其他函数的调用而改变。
  • sizeof(arr) 的值不取决于您分配给它的内容。它是在编译时计算的,它总是等于指针的大小。在您的系统上,指针使用 8 个字节。
  • malloc 通常会为您提供更多所需的内存,并将实际值存储在 realloc 以后可以访问的特殊位置。如果realloc 向下或realloc 在界限内,realloc 返回的值不会改变。这就是为什么它可能比简单地调用mallocmemcpy 表现更好的原因。

【讨论】:

  • 感谢您的回答(我显然认为这是最准确的,尽管 Ed 的回答也很棒)。关于堆栈与堆,我只是想确保我没有错误地分配并用堆栈覆盖它的一部分。在原始程序中,我遇到的问题看起来像是某些字符串被覆盖了(它们是;我重新分配的空间比必要的小得多),所以这就是那里的原因。
【解决方案2】:
sizeof arr

一样
sizeof char**

指针的大小不会改变,并且获取指针的大小不会告诉您它引用了多少内存。指针不是数组,sizeof 在编译时进行评估。

至于地址位,realloc 不保证内存块被移动了。它可以简单地成功扩展它并返回相同的地址。

另外,我知道这只是示例代码,但请注意,如果 realloc 失败,您会泄露 arr 最初指向的内容。

【讨论】:

  • Pedantic:在 C99 中,sizeof 可以是运行时操作(如果用于可变长度数组)。见stackoverflow.com/q/10078283/575615
  • @Medo42:啊,是的,好电话。我在 C89 领域写 C 有一段时间了,没想到。
【解决方案3】:

malloc 调用后面紧跟realloc 不会改变指针的地址,这种情况并不少见,实际上有点意料之中。在许多情况下,分配器可以只扩展在地址处保留的内存量,而不必移动指针。这就是这里发生的事情。

不过,这不是你应该依赖的东西。这只是实现的一个怪癖

【讨论】:

  • 这根本不是这个问题所关注的。
【解决方案4】:

如果您的假设是 realloc() 必须返回不同的指针,那么您的假设是错误的。

通常,如果您要减少分配的内存大小或保持“原样”,则realloc() 可以返回相同的指针并避免复制数据等。

有时,如果您要增加分配内存的大小,realloc() 可以检查现有空间上方是否有可用空间并仍然返回相同的指针(并避免复制数据)。

大多数情况下,只有在分配的内存上方没有可用空间时,realloc() 必须将数据复制到其他地方并返回不同的指针。

【讨论】:

    猜你喜欢
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多