realloc()递增的指针 平台:Linux 3.2.0 x86(Debian Wheezy) 编译器:GCC 4.7.2(Debian 4.7.2-5)
我想知道,如果我尝试realloc()一个已经递增的指针,会发生什么。比如说realloc()递增的指针 平台:Linux 3.2.0 x86(Debian Wheezy) 编译器:GCC 4.7.2(Debian 4.7.2-5),c,malloc,C,Malloc,我想知道,如果我尝试realloc()一个已经递增的指针,会发生什么。比如说 char *ptr = NULL; size_t siz = 256; ptr = malloc(siz); ptr = realloc(ptr + 5, siz * 2); realloc()调用的返回值是多少?我还知道,realloc()的文档说明传递给它的指针必须由malloc()、calloc()或realloc()返回。我假设这意味着我无法realloc()递增指针,但我无法验证这一假设。这将无法以任何
char *ptr = NULL;
size_t siz = 256;
ptr = malloc(siz);
ptr = realloc(ptr + 5, siz * 2);
realloc()
调用的返回值是多少?我还知道,realloc()
的文档说明传递给它的指针必须由malloc()、calloc()
或realloc()
返回。我假设这意味着我无法realloc()
递增指针,但我无法验证这一假设。这将无法以任何可预测的方式工作,结果将是未定义的。传递给realloc
或free
的第一个参数必须由malloc
、realloc
或calloc
返回,或者必须为NULL
在这种情况下,ptr[5]
不是这样,因为ptr[5]
未初始化。您还将收到编译错误或警告,因为ptr[5]
不是指针。但是,即使它是一个指针(例如,char**ptr;
),它仍然是未初始化的,因此条件为false,因此结果未定义,并且进程很可能会崩溃
在这种情况下,
ptr+5
也不是这样,因为ptr+5
不是由malloc
、realloc
或calloc
(但是ptr
was)返回的,它不是NULL
。行为未定义在这种情况下,进程很可能会崩溃。正如pts所说,行为未定义。我预计您将得到一个segfault,但如果不进行测试,您无法知道它在您的特定系统上的行为
试用:
收益率:
*** Error in `./prog': realloc(): invalid pointer: 0x09dc900d ***
======= Backtrace: =========
/lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x75e72)[0xb7641e72]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(realloc+0x275)[0xb7645ad5]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(realloc+0x28b)[0xb7645aeb]
./prog[0x80483e8]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(__libc_start_main+0xf5)[0xb75e58f5]
./prog[0x804840d]
malloc的实现因系统而异,但基本思想是,在某个地方,您的操作系统。当您调用
realloc
时,它会在其查找表中查找您传递给它的地址。它找不到它,所以它放弃并转储内核 malloc
family函数分配内存,然后返回指向该块的指针ptr+5
不是由malloc
返回的,因此不能将其传递给realloc
,因为它希望其第一个参数是由calloc
或malloc
本身返回的指针。它将调用未定义的行为
C11:7.22.3.3:
[…]否则,如果参数与内存管理函数先前返回的指针不匹配,或者如果通过调用free
或realloc
释放空间,则行为未定义
与其说
&ptr[5]
未初始化,还不如说它不是malloc()
返回的值。我不是指取消引用,我实际上是指指针算术的动词等价物。@Jonathan Leffler:ptr[5]
在这种情况下确实未初始化,因此,它不能初始化为由malloc
、realloc
或calloc
返回的值。是的,ptr[5]
确实未初始化,但这对问题(修订版)无关紧要。问题是ptr+5
不是由malloc()
返回的。我的答案涵盖了问题的旧版本和新版本(到目前为止)。当你写“取消引用”时,实际上是指“添加到”。取消引用意味着应用*
或[]
运算符。
*** Error in `./prog': realloc(): invalid pointer: 0x09dc900d ***
======= Backtrace: =========
/lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x75e72)[0xb7641e72]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(realloc+0x275)[0xb7645ad5]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(realloc+0x28b)[0xb7645aeb]
./prog[0x80483e8]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(__libc_start_main+0xf5)[0xb75e58f5]
./prog[0x804840d]