Realloc根本不做任何事情,而不是错误

时间:2014-01-26 01:20:27

标签: c malloc realloc

我有以下代码:

#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>

其中<size>是......奇怪的是12 ...至少不是8而<somewhere>最有可能是0x120f010,但可能是合理的。

我的期望是错误还是我错误地使用realloc?

4 个答案:

答案 0 :(得分:1)

sizeof arr

相同
sizeof char**

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

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

这种情况并不少见,事实上有点预期,malloc直接跟随realloc的调用不会改变指针的地址。在许多情况下,分配器只能扩展在地址处保留的内存量,而不必移动指针。这就是这里发生的事情。

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

答案 3 :(得分:0)

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

通常,如果您正在减小已分配内存的大小或“按原样”保留它,那么realloc()可以返回相同的指针并避免复制数据等。

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

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