目录
malloc
好处
坏处
总结
calloc
参数说明
作用
与 malloc 的区别
示例
优点
缺点
总结
realloc
参数说明
作用
示例
优点
缺点
注意事项
总结
总结区别
对比表格
malloc
函数功能:分配内存给
void* malloc(size_t size);
来看一下deepseek的解释,其实deepseek的解释好,涵盖了很多方面
malloc 是 C 语言中用于动态分配内存的函数,其原型为:
size:需要分配的内存大小(以字节为单位)。
返回值:成功时返回指向分配内存的指针,失败时返回 NULL。
好处
动态内存分配:程序运行时根据需要分配内存,避免静态分配的局限性。
灵活管理内存:适用于不确定内存需求的情况,如动态数组、链表等数据结构。
提高资源利用率:按需分配,减少内存浪费。
坏处
内存泄漏:未使用 free 释放内存会导致内存泄漏,长期运行可能耗尽系统资源。
碎片化:频繁分配和释放可能导致内存碎片,降低内存使用效率。
性能开销:动态分配比静态分配慢,频繁操作可能影响性能。
未初始化内存:malloc 分配的内存未初始化,直接使用可能导致未定义行为。
总结
malloc 提供了动态内存分配的灵活性,但需谨慎管理以避免内存泄漏和碎片化问题。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
//malloc 分配内存
void test01() {
int *p = malloc(sizeof(int)*10);
for (int i = 0; i< 10; i++)
{
printf("p[%d] = %d\n",i,p[i]);
}
}
int main() {
printf("mamory info\n");
test01();
return EXIT_SUCCESS;
}
运行结果:
赋值
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
//malloc 分配内存
void test01() {
int *p = malloc(sizeof(int)*10);
for (int i = 0; i< 10; i++)
{
p[i] = i + 100;
}
for (int i = 0; i < 10; i++)
{
printf("p[%d] = %d\n", i, p[i]);
}
}
int main() {
printf("mamory info\n");
test01();
return EXIT_SUCCESS;
}
calloc
#include
void *calloc(size_t nmemb, size_t size);
功能
calloc 是 C 语言中用于动态分配内存的函数,与 malloc 类似,但它在分配内存的同时会将内存初始化为零。其原型为
参数说明
num:需要分配的元素个数。
size:每个元素的大小(以字节为单位)。
返回值:成功时返回指向分配内存的指针,失败时返回 NULL。
作用
分配内存:分配 num * size 字节的内存空间。
初始化内存:将分配的内存块中的所有位初始化为零。
与 malloc 的区别
特性malloccalloc初始化不初始化内存,内容为随机值初始化内存为 0参数接受总字节数接受元素个数和每个元素的大小适用场景不需要初始化时使用需要初始化内存为零时使用
示例
#include
#include
int main() {
int *arr;
int n = 5;
// 使用 calloc 分配并初始化内存
arr = (int*)calloc(n, sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// 打印初始化的值(应为 0)
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]); // 输出: 0 0 0 0 0
}
// 释放内存
free(arr);
return 0;
}
优点
自动初始化:省去手动初始化的步骤,避免使用未初始化的内存。
适合数组和结构体:特别适合需要初始化为零的场景,如数组、结构体等。
缺点
性能开销:由于需要初始化内存,calloc 的性能略低于 malloc。
不适用于非零初始化:如果不需要初始化为零,使用 malloc 更高效。
总结
calloc:适合需要分配并初始化内存为零的场景。
malloc:适合不需要初始化或需要手动初始化的场景。
根据具体需求选择合适的函数!
//calloc 分配内存
void test02() {
//参数1长度,参数2类型的大小
int* p = calloc(10,sizeof(int)); //与malloc的不同是在于堆区的内容初始化成0,相同的地方都是在堆区分配内存
for (int i = 0; i < 10; i++)
{
printf("p[%d] = %d\n", i, p[i]);
}
if (p!= NULL) {
free(p);
p = NULL;//防止野指针
}
}
int main() {
printf("mamory info\n");
test02();
return EXIT_SUCCESS;
}
realloc
realloc重新分配内存,在原有的内存上加更多内存
realloc 是 C 语言中用于调整已分配内存块大小的函数。它可以在不丢失原有数据的情况下,扩大或缩小内存块的大小。其原型为:
void* realloc(void* ptr, size_t size);
参数说明
ptr:指向之前分配的内存块的指针(由 malloc、calloc 或 realloc 返回)。如果 ptr 为 NULL,则 realloc 的行为等同于 malloc。
size:新的内存块大小(以字节为单位)。如果 size 为 0 且 ptr 不为 NULL,则 realloc 的行为等同于 free。
返回值:成功时返回指向新内存块的指针,失败时返回 NULL,且原内存块保持不变。
作用
调整内存大小:
扩大内存块:如果新的大小大于原大小,realloc 会尝试扩展内存块,保留原有数据。
缩小内存块:如果新的大小小于原大小,realloc 会截断内存块,保留新大小范围内的数据。
重新分配内存:
如果原内存块无法扩展,realloc 会分配一个新的内存块,将原数据复制到新内存块中,并释放原内存块。
释放内存:
如果 size 为 0 且 ptr 不为 NULL,realloc 会释放原内存块,并返回 NULL。
示例
#include
#include
int main() {
int *arr;
int n = 5;
// 初始分配内存
arr = (int*)malloc(n * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// 初始化数据
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
// 调整内存大小
int new_n = 10;
arr = (int*)realloc(arr, new_n * sizeof(int));
if (arr == NULL) {
printf("Memory reallocation failed\n");
return 1;
}
// 初始化新增部分
for (int i = n; i < new_n; i++) {
arr[i] = i + 1;
}
// 打印结果
for (int i = 0; i < new_n; i++) {
printf("%d ", arr[i]); // 输出: 1 2 3 4 5 6 7 8 9 10
}
// 释放内存
free(arr);
return 0;
}
优点
动态调整内存:可以根据需要动态调整内存大小,避免内存浪费。
保留数据:在扩展内存时,原有数据会被保留。
灵活性:适合处理动态变化的数据结构,如动态数组、链表等。
缺点
性能开销:如果无法在原内存块上扩展,realloc 需要分配新内存并复制数据,这会带来额外的性能开销。
内存碎片:频繁调整内存大小可能导致内存碎片。
潜在的内存泄漏:如果 realloc 失败并返回 NULL,原内存块不会被释放,可能导致内存泄漏。
注意事项
检查返回值:realloc 可能失败,返回 NULL,因此需要检查返回值。
避免直接覆盖指针:
ptr = realloc(ptr, new_size); // 错误:如果 realloc 失败,ptr 会丢失
正确做法:
void *new_ptr = realloc(ptr, new_size);
if (new_ptr == NULL) {
// 处理错误
} else {
ptr = new_ptr;
}
释放内存:使用 realloc 后,仍需使用 free 释放内存。
总结
realloc 是动态内存管理的重要工具,适合需要动态调整内存大小的场景。
使用时需注意检查返回值,避免内存泄漏和性能问题。
结合 malloc、calloc 和 free,可以实现灵活的内存管理。
情况1:分配的大小足够,不会继续增加。可以看运行结果,地址内存不会变
//realloc重新分配内存
void test03() {
int* p = malloc(sizeof(int)*10);
printf("p: %d\n", &p);
for (int i = 0; i < 10; i++) {
p[i] = i;
}
p = realloc(p,sizeof(int)*11); //在原有的基础上加11,如果原有的内存不够,才会增加
for (int i = 0; i < 10; i++) {
printf("p[%d] = %d\n",i,p[i]);
}
printf("p: %d\n", &p);
}
int main() {
printf("mamory info\n");
//test01();
//test02();
test03();
return EXIT_SUCCESS;
}
运行结果:
总结区别
对比表格
特性malloccallocrealloc功能分配内存分配并初始化内存调整已分配内存的大小初始化不初始化初始化为零保留原有数据(如果可能)参数总字节数 (size)元素个数 (num) 和元素大小 (size)原指针 (ptr) 和新大小 (size)返回值指向分配内存的指针指向分配内存的指针指向新内存块的指针适用场景不需要初始化时使用需要初始化内存为零时使用需要调整内存大小时使用
malloc:适合不需要初始化内存的场景。
calloc:适合需要初始化内存为零的场景。
realloc:适合需要动态调整内存大小的场景。
查看接口
cplusplus.com - The C++ Resources Networkhttps://legacy.cplusplus.com/