我有一个简化的C程序,它演示了这个问题。当我尝试使用指针调用realloc
时,它工作正常,但如果我尝试向指针添加一个偏移量(即从数组中的后一个元素开始),它就会失败。
# include <stdio.h>
# include <stdlib.h>
struct arbNum{
unsigned char* bytes;
long len;
};
void trim(struct arbNum* num){
printf("%d,%d,%d,%d\n",num->bytes,num->bytes[0],num->bytes[1],num->len);
unsigned char* nbytes = realloc(num->bytes,num->len);
printf("Realloc successful.\n");
num->bytes = nbytes;
}
int main(void){
struct arbNum p = {calloc(2,1),2};
trim(&p);
}
例如,输出:
9247152,0,0,2
Realloc successful.
但是,从上面的代码中,将realloc(num->bytes,num->len);
更改为realloc(num->bytes+1,num->len-1);
会将输出/行为更改为:
10361264,0,0,2
然后崩溃。可能我根本不理解指针,但我目前的理解是它们本质上是存储另一个值的地址。在这种情况下,为什么提供pointer+1
不指向存储在高于指针的地址中的值,或者换句话说,什么将充当该指针所指向的数组的第一个元素。我试图做的是将{1}从第一个元素开始指向的数组复制到内存中的新地址,但很明显,它因某种原因失败了。
答案 0 :(得分:7)
不,您只能realloc()
查看malloc()
或家人之前返回的实际指针。
否则,它是undefined behavior
引用C11
,章节§7.22.3.5
如果
ptr
是空指针,则realloc
函数的行为类似于malloc
函数 指定大小。否则,如果ptr
与先前由内存返回的指针不匹配 管理功能,或者如果通过调用free
或已释放空间realloc
函数,行为未定义。 [....]
所以,你不是允许使用指针aritmatic去生成一个新地址,将其传递给realloc()
并期望部分重新分配,这没有任何意义。