问题历史:
动态内存分配机制在C语言中与标准库函数malloc/free一起出现,定义在<stdlib.h>中。它们允许实现可变大小的结构、复杂集合和对象,这为语言的发展和在大规模编程中的应用提供了强有力的推动。
问题:
处理动态内存要求程序员对对象的生命周期进行完全控制。错误(内存泄漏、双重释放、错误使用指针)可能导致崩溃或安全漏洞(例如,通过错误的use-after-free攻击)。
解决方案:
— 始终检查malloc/calloc/realloc的返回值。如果分配失败,它们将返回NULL。 — 释放内存后,将指针设置为NULL,以避免使用已释放的内存块。 — 不要在free后使用指针。 — 确保malloc/free与calloc/free的正确配对。
代码示例:
#include <stdio.h> #include <stdlib.h> int main() { int *arr = malloc(5 * sizeof(int)); if (!arr) { perror("内存分配失败"); return 1; } for (int i = 0; i < 5; ++i) arr[i] = i * i; for (int i = 0; i < 5; ++i) printf("%d ", arr[i]); printf(" "); free(arr); arr = NULL; return 0; }
关键特性:
如果使用delete释放通过malloc分配的内存,或反之(在C++中)会发生什么?
不能混合语言之间的内存分配和释放机制(C/C++)。在C中—仅使用malloc/free,在C++中—使用new/delete。
调用free(NULL)会发生什么?
free(NULL)是安全的(这是C标准所保证的)。这样的调用什么也不做。
可以使用realloc来增加或减少内存块吗?原始指针会发生什么?
realloc可能会移动内存块,如果发生移动,旧指针将变为无效。始终分配新指针:
ptr = realloc(ptr, new_size);
在循环中为数组分配内存,但忘记在每次迭代结束时释放。结果,程序在服务器上“吞掉”了全部RAM。
优点:
缺点:
在循环中始终在使用后释放内存,所有对NULL的检查在malloc后立即执行,并使用调试工具监控泄漏。
优点:
缺点: