📜  C |动态内存分配|问题3(1)

📅  最后修改于: 2023-12-03 14:59:37.961000             🧑  作者: Mango

C动态内存分配问题3

在C语言中,动态内存分配是一个非常有用的机制,它让程序员可以在程序运行时动态地分配和释放内存。但是,如果程序员不小心使用动态内存分配,就很容易出现一些问题。本文将介绍在C语言中使用动态内存分配时可能遇到的一些问题和解决方案。

问题描述

在C语言中,如果程序员使用malloc()函数分配了一段内存,然后又使用realloc()函数重新分配了这段内存的大小,那么原来分配的内存地址是否还有效?

int *p = malloc(10 * sizeof(int)); // 分配10个int型变量大小的内存
p = realloc(p, 20 * sizeof(int));  // 重新分配20个int型变量大小的内存
printf("%p", p); // 输出p的地址

在上面的代码中,我们首先使用malloc()函数分配了10个int型变量大小的内存,并将其保存在指针p中。然后,我们使用realloc()函数重新分配了这段内存的大小,并将其扩展到20个int型变量大小。最后,我们输出了指针p的地址。请问,这个代码能否正确地输出p的地址?

问题分析

根据C语言的内存管理机制,当我们使用malloc()函数分配内存时,它会在堆上分配一段连续的内存,并返回一个指向这段内存的指针。而当我们使用realloc()函数重新分配这段内存时,它会在堆上为我们重新分配一段连续的内存,并返回一个指向这段内存的指针。但是,这个新的指针并不一定与原来的指针相同,而且这个新的指针也不一定指向原来的内存地址。因此,如果我们在realloc()函数执行之后仍然使用原来的指针p,就有可能出现一些问题。因为此时p指向的地址可能已经不是我们分配的那块内存的起始地址了。

解决方案

为了解决这个问题,我们可以在调用realloc()函数之后使用一个新的指针来保存它的返回值,然后再使用这个指针访问新分配的内存空间。对于原来的指针p,我们可以将它置为NULL,这样就可以避免使用它访问非法的内存地址了。

int *p = malloc(10 * sizeof(int)); // 分配10个int型变量大小的内存
int *newp = realloc(p, 20 * sizeof(int));  // 重新分配20个int型变量大小的内存
if (newp != NULL) {
  p = newp;
  // 使用p来访问新分配的内存空间
} else {
  // 重新分配内存失败
  // 这时应该释放原来的指针p,然后结束程序
  free(p);
  exit(1);
}
// 使用p来访问新分配的内存空间
// ...
// ...
// 当p不再需要使用时,应该将它置为NULL
p = NULL;

在上面的代码中,我们首先使用malloc()函数分配了10个int型变量大小的内存,并将其保存在指针p中。然后,我们使用realloc()函数重新分配了这段内存的大小,并将其扩展到20个int型变量大小。注意,我们将realloc()函数的返回值保存在了一个新的指针newp中,并在realloc()函数返回NULL时退出程序。最后,我们使用指针p来访问新分配的内存空间,并将其置为NULL。

总结

在C语言中,使用动态内存分配是非常有用的机制,但是也有一些需要注意的问题。在使用malloc()函数分配内存之后,如果需要使用realloc()函数重新分配这段内存的大小,那么在realloc()函数执行之后应该使用一个新的指针来保存它的返回值,并将原来的指针置为NULL,从而避免使用非法的内存地址。