如果'a'指向一个有效的内存块(来自先前的malloc/realloc/calloc),那么realloc调用将尝试提供您请求的新大小的内存块。
realloc调用应该是这样的形式:
*tmp = realloc(a ...
必须测试realloc的返回值。如果它为NULL,则realloc无法分配所请求的内存,这将使'a'成为有效指针。然后,您需要负责处理由'a'指向的任何数据(保存/丢弃它),并负责释放'a'指向的内存。
如果realloc调用成功,请使
b = tmp
,现在'b'是指向内存块的新指针 - 开始位置是否与'a'相同并不重要。'a'不再是有效的内存分配指针,尽管进一步的错误取决于'a'是否指向您的程序拥有的内存 - 基本上,如果a == b,则可以访问'a'而不会出现明显的错误。
在有效的*tmp = realloc(a ...
& b = tmp;
之后:
1)如果重新分配内存的起始位置未更改:(a == b)
它将分配请求的内存
但在valgrind下运行,您会看到错误消息:
Invalid free() / delete / delete[] / realloc()
Address 0x51fc040 is 0 bytes inside a block of size 256 free'd
在这种情况下,realloc无法释放'a'指向的内存
并且再次在这种情况下,'a'仍然可以被访问,因为它是分配给您的程序的内存的指针
2)如果重新分配内存的起始位置已更改:(a != b)
它将失败,Valgrind显示以下输出:
a的地址:0x1e89010
b的地址:0x7f2c5893c010
realloc后的a:0x1e89010
错误:“./test15”中的realloc():无效的旧大小:0x0000000001e89010
尝试访问'a'将会失败 - 即使尝试将其值作为指针打印出来也会失败,这可能是因为它不再指向程序拥有的内存。
换句话说,在b = realloc(a ...
之后使用'a'是未定义的行为。
上述评论是基于使用以下代码:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *a = NULL, *b = NULL, *c = NULL;
a = malloc(256);
if( a == NULL) return (1);
printf("address of a: %p\n", a);
void *tmp = realloc(a, 512);
if ( !tmp ) {
free(a);
return (1);
} else {
b = tmp;
}
printf("address of b: %p\n", b);
printf("a after realloc: %p\n", a);
c = realloc(a, 256);
printf("return value of c: %p\n", c);
if (c != NULL) {
free(c);
printf("'c' allocated\n");
} else {
free(b);
printf("'c' not allocated\n");
}
return 0;
}
realloc()
规范以及Linux手册或任何手册。行为并不完全一致,它取决于情况。此外,不要像那样编写没有int
返回类型的main()
,那真的很老旧和不建议使用 [标签:c]。 - Iharob Al Asimi