首先,我为我糟糕的英语感到抱歉。
我对C语言中的“realloc”函数有一个疑问。我认为它用给定的长度分配记忆。当内存对给定长度不够时,它将整个内存复制到另一个内存指针并返回它。
我想用realloc函数来保存旧的记忆。所以我判了另一个指针,让它指向过去的记忆。但是,每当“realloc”函数起作用时,它就会释放旧的记忆。我怎样才能保存旧的记忆?另外,我想知道为什么会这样。
下面是用于测试realloc函数的代码及其结果。
#include <stdio.h>
#include <stdlib.h>
int* ptr1, lenPtr1;
int* ptr2;
void double_ptr1(){
lenPtr1 *= 2;
ptr1 = (int*)realloc(ptr1, sizeof(int) * lenPtr1);
}
void print(){
printf("ptr1 -> %p, *ptr1 = %d\n", ptr1, *ptr1);
printf("ptr2 -> %p, *ptr2 = %d\n", ptr2, *ptr2);
printf("\n");
}
int main(){
lenPtr1 = 10;
ptr1 = (int*)malloc(sizeof(int) * lenPtr1);
ptr2 = ptr1;
*ptr1 = 10;
print();
double_ptr1();
print();
system("pause");
return 0;
}ptr1 -> 0108D2F0,*ptr1 = 10 ptr2 -> 0108D2F0,*ptr2 = 10
ptr1 -> 00FF5740,*ptr1 = 10 ptr2 -> 0108D2F0,*ptr2 = -17891602
发布于 2020-10-12 00:50:16
一个包含注释中建议的所有改进并避免使用全局变量的示例,并在程序退出之前释放所有分配的内存。只需要将终端窗口打开在窗口上,因此有条件地将system("pause");括起来。
总之,你应该有:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *double_ptr (int *ptr, int *ptrsz) /* pass needed information as parameters */
{
int *newptr = malloc (2 * *ptrsz * sizeof *newptr); /* allocate new block of mem */
if (newptr) { /* validate allocation */
memcpy (newptr, ptr, *ptrsz * sizeof *ptr); /* copy to new block of mem */
*ptrsz *= 2; /* update allocated size */
}
return newptr; /* return pointer */
}
void print (int *ptr1, int *ptr2) /* pass needed information as parameters */
{
/* only one call to printf required */
printf ("ptr1 -> %p, *ptr1 = %d\nptr2 -> %p, *ptr2 = %d\n\n",
(void*)ptr1, *ptr1, (void*)ptr2, *ptr2);
}
int main (void) {
int *ptr1 = NULL, *ptr2 = NULL, lenPtr1 = 10; /* avoid global variables */
if (!(ptr1 = malloc (lenPtr1 * sizeof *ptr1))) { /* validate EVERY allocation */
perror ("malloc-ptr");
return 1;
}
ptr2 = ptr1; /* pointer 1 and 2 hold same address where 10 is stored in memory */
*ptr1 = 10;
printf ("lenPtr1: %d\n", lenPtr1); /* output len, addresses, values */
print (ptr1, ptr2);
if (!(ptr1 = double_ptr (ptr1, &lenPtr1))) { /* double size of ptr1 */
perror ("malloc-double-ptr1");
return 1;
}
printf ("lenPtr1: %d\n", lenPtr1); /* output len, addresses, values */
print (ptr1, ptr2);
free (ptr1); /* free allcoated memory */
free (ptr2);
#if defined (_WIN32) || defined (_WIN64)
system("pause");
#endif
}示例使用/输出
$ ./bin/doubleptrsz
lenPtr1: 10
ptr1 -> 0xb18260, *ptr1 = 10
ptr2 -> 0xb18260, *ptr2 = 10
lenPtr1: 20
ptr1 -> 0xb186a0, *ptr1 = 10
ptr2 -> 0xb18260, *ptr2 = 10如果你还有其他问题,请告诉我。
发布于 2020-10-12 00:27:02
当您实际指定由ptr2指向的原始指针时,原始指针的地址将被移除。
因此,在您重新分配ptr1之后,ptr2点地址就不再存在了。
如果您想要保留旧内存,那么您只需要将malloc(或calloc)新内存保留到ptr1,而不需要realloc原始内存。
发布于 2020-10-12 01:08:39
当内存对给定长度不够时,它将整个内存复制到另一个内存指针并返回它。
不完全是。realloc 总是释放旧内存。它可能返回相同的指针。
C11 7.20.3.4 realloc.
realloc函数释放
ptr指向的旧对象,并返回指向具有size指定大小的新对象的指针.realloc函数返回指向新对象的指针(该对象的值可能与指向旧对象的指针相同)。我想用realloc函数来保存旧的记忆。
你不能这么做。
如果您需要更多的内存,malloc是一个新内存块,而不是重新分配旧内存。
如果要缩小内存,请继续按原样使用内存。一切都会好的,这只是在浪费记忆。
我都不推荐。相反,重新设计您正在做的任何操作,以便间接访问指针。也许使用指向指针的指针。或者将指针放入结构中,并传递指向该结构的指针。
或者,重新设计它,这样你就不需要再现实了。例如,当从文件读取时,使用固定大小的缓冲区读取行,然后以足够的空间将其复制到内存中。
// A large buffer to reuse for each line.
char buf[BUFSIZ];
while( fgets(buf, sizeof(buf), fp) ) {
// Allocate exactly enough space for the line.
// In reality, use strdup.
char *string = malloc(strlen(buf) + 1);
strcpy(string, buf);
}或者更改为不依赖于单个内存块的数据结构。例如,链表而不是数组。
此外,我想知道为何会出现这种情况。
malloc有许多实现。,但它们都必须分配没有重叠的连续内存块。
考虑两个对malloc的调用。
char *foo = malloc(8);
char *bar = malloc(8);假设foo和bar被分配给相邻的内存块,如下所示。(注:不能保证它们会相邻,而且有很多理由不能保证它们是相邻的。)
0123456789abcdef0123456789abcdef
^^^^^^^^
| ^^^^^^^^
foo |
bar现在你试着长胖了。
foo = realloc(foo, 16);如果realloc试图保持相同的指针,foo将不得不重叠到bar的内存中。
0123456789abcdef0123456789abcdef
^^^^^^^^^^^^^^^^
| ^^^^^^^^
foo |
bar这是不允许的,分配不能重叠。它们也必须是连续的,因此它不能这样做:
0123456789abcdef0123456789abcdef
^^^^^^^^ ^^^^^^^^
| ^^^^^^^^
foo |
bar如果允许它这样做,指针数学就不能工作。您将无法可靠地添加到foo以遍历其分配的内存。
因此realloc必须释放foo并分配一个新块。(同样,也不能保证分配到哪里。)
0123456789abcdef0123456789abcdef
^^^^^^^^
| ^^^^^^^^^^^^^^^^
bar |
foohttps://stackoverflow.com/questions/64310236
复制相似问题