realloc()
如何重新分配由malloc()
首先分配的内存?
[我知道,您需要先使用malloc()
,然后才能重新分配内存,但是我不知道它应该如何工作以及如果动态内存对象的大小减小了[ C0]?是在调用realloc()
之后刚刚擦除的各个对象吗?
我的问题是:
realloc()
函数如何重新分配由realloc()
创建的动态内存对象?注:我进行了此问题与解答,因为许多初学者似乎仍然对使用malloc()
重新分配内存的问题感到困惑,尽管此处已经存在关于该主题的问题。对于刚接触该主题但仍不代表realloc()
整个行为的任何人,它们似乎有些困惑。因此,也是我的原因,恕我直言,这些问题仍不完全符合我想要给出的答案,我进行了自己的问答。
注:以下答案中的所有引用均来自实际的C标准,ISO / IEC 9899:2018(C18),第7.23.2.4节。
首先,来自ISO / IEC 9899:2018,第7.22.3.4节的realloc()
功能的提要:
realloc()
尽管有其名称,#include <stdlib.h>
void *realloc(void *ptr, size_t size);
函数不会“ re分配”任何内容。 realloc()
是not修改内存中的现有对象。相反,它执行某种“创建(新对象)并复制数据”例程。
[如果realloc()
的指针必须指向一个对象,该指针首先由任何一个内存管理功能(不仅限于ptr
分配),要么指向malloc()
,并且NULL
为通常不是size
,0
创建一个新对象并将realloc()
指向的旧对象的数据复制到该新对象中。
**我确实说通常,因为您不能假设实际上已经分配了一个内存中的新对象。如果指向ptr
,则始终必须通过证明返回的指针来检查它是否已分配。
如果新对象的大小大于旧对象,则新对象中超出旧对象大小的部分具有不确定的值。如果新对象短于旧对象,则两者之间的差之内的值将被丢弃。
新对象的内容应与重新分配之前的旧对象相同,直到新旧大小中的较小者为止。新对象中超出旧对象大小的任何字节都具有不确定的值。
此后,
If,
NULL
是not指向ptr
的指针,并且is之前由其所指向的对象的内存管理函数返回的指针,直到调用NULL
时才释放(或至少指向以前以这种方式分配的对象,直到realloc()
调用时才释放)
如果ptr是空指针,则对于指定的大小,realloc函数的行为类似于malloc函数。否则,如果ptr与内存管理函数先前返回的指针不匹配,或者如果通过调用free或realloc函数已经释放了空间,则该行为是不确定的。
[realloc()
不是size
,
如果size为零,并且未分配新对象的内存,则是否释放旧对象由实现定义。如果旧对象未释放,则其值应保持不变。
并且可以真正分配一个新对象/ 0
没有返回指向realloc()
的指针,
如果大小为非零并且未分配新对象的内存,则不会释放旧对象
并且仅当满足这些前提的[[all
NULL
才释放旧对象的内存并返回带有新对象地址的指针在内存中。realloc函数将分配由realloc()
指向的旧对象,并返回指向具有由ptr
指定的大小的新对象的指针。如果
size
返回指向realloc()
的指针,则不会创建任何新对象,并且旧对象在内存中的地址保持不变。
realloc函数返回一个指向新对象的指针(该值可能与指向旧对象的指针的值相同;如果未分配新对象,则返回一个空指针。在这种情况下,
NULL
中发生了两个数据复制过程。一次进入缓冲对象,然后又回到原始的旧对象的位置。realloc()
的执行完成后,将释放缓冲区对象。
realloc()
的指针首先用于指向旧对象,也可以用于返回的指针。然后,对ptr
的调用语句将如下所示:realloc()
从技术上讲,ptr = realloc(ptr,size);
只是在这种情况下修改realloc()
内部的地址值,从旧对象的地址更改为新对象的地址。请注意,根据我上面所述,地址可能与调用ptr
之前的地址相同。
realloc()
在我的尝试下,它给出了输出:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
size_t length1 = 4;
size_t length2 = 2;
int *ptr1 = malloc(sizeof(*ptr1) * length1);
if(ptr1 == NULL)
{
printf("The object could not be allocated!");
return 1;
}
printf("value (not address) of ptr1 before realloc(): %p\n",ptr1);
ptr1 = realloc(ptr1,length2);
if(ptr1 == NULL)
{
printf("No new object allocated. Old object remains!");
return 1;
}
printf("value (not address) of ptr1 after realloc(): %p\n",ptr1);
return 0;
}
因此,在使用value (not address) of ptr1 before realloc(): 0x1db4010
value (not address) of ptr1 after realloc(): 0x1db4010
之后存储在ptr1中的地址等于调用它之前的地址。
附加说明:
realloc()
realloc()
是malloc()
指针时充当ptr
:NULL
与具有相同的作用,
int *ptr = NULL;
size_t length = 4;
ptr = realloc(ptr,sizeof(*ptr) * length);
如果ptr是空指针,则对于指定的大小,realloc函数的行为类似于malloc函数。
但是您不应该首先使用int *ptr;
size_t length = 4;
ptr = malloc(sizeof(*ptr) * length);
分配动态存储。始终使用realloc()
。
malloc()
代替realloc(ptr,0)
来释放动态内存存储,因为它由实现来定义对象是否真正释放。 如果size为零,并且未分配新对象的内存,则是否释放旧对象由实现定义。如果旧对象未释放,则其值应保持不变。
始终使用free(ptr)
释放动态分配的对象。