当前位置: 首页 > news >正文

11.C语言 malloc() calloc() realloc()分配内存

目录

malloc

好处

坏处

总结

calloc

参数说明

作用

与 malloc 的区别

示例

优点

缺点

总结

realloc

参数说明

作用

示例

优点

缺点

注意事项

总结

总结区别

对比表格


malloc

函数功能:分配内存给

void* malloc(size_t size);

来看一下deepseek的解释,其实deepseek的解释好,涵盖了很多方面

malloc 是 C 语言中用于动态分配内存的函数,其原型为:

  • size:需要分配的内存大小(以字节为单位)。

  • 返回值:成功时返回指向分配内存的指针,失败时返回 NULL

好处

  1. 动态内存分配:程序运行时根据需要分配内存,避免静态分配的局限性。

  2. 灵活管理内存:适用于不确定内存需求的情况,如动态数组、链表等数据结构。

  3. 提高资源利用率:按需分配,减少内存浪费。

坏处

  1. 内存泄漏:未使用 free 释放内存会导致内存泄漏,长期运行可能耗尽系统资源。

  2. 碎片化:频繁分配和释放可能导致内存碎片,降低内存使用效率。

  3. 性能开销:动态分配比静态分配慢,频繁操作可能影响性能。

  4. 未初始化内存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 <stdlib.h>
void *calloc(size_t nmemb, size_t size);

功能

calloc 是 C 语言中用于动态分配内存的函数,与 malloc 类似,但它在分配内存的同时会将内存初始化为零。其原型为

参数说明

  • num:需要分配的元素个数。

  • size:每个元素的大小(以字节为单位)。

  • 返回值:成功时返回指向分配内存的指针,失败时返回 NULL

作用

  1. 分配内存:分配 num * size 字节的内存空间。

  2. 初始化内存:将分配的内存块中的所有位初始化为零。

与 malloc 的区别

特性malloccalloc
初始化不初始化内存,内容为随机值初始化内存为 0
参数接受总字节数接受元素个数和每个元素的大小
适用场景不需要初始化时使用需要初始化内存为零时使用

示例

#include <stdio.h>
#include <stdlib.h>

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;
}

优点

  1. 自动初始化:省去手动初始化的步骤,避免使用未初始化的内存。

  2. 适合数组和结构体:特别适合需要初始化为零的场景,如数组、结构体等。

缺点

  1. 性能开销:由于需要初始化内存,calloc 的性能略低于 malloc

  2. 不适用于非零初始化:如果不需要初始化为零,使用 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:指向之前分配的内存块的指针(由 malloccalloc 或 realloc 返回)。如果 ptr 为 NULL,则 realloc 的行为等同于 malloc

  • size:新的内存块大小(以字节为单位)。如果 size 为 0 且 ptr 不为 NULL,则 realloc 的行为等同于 free

  • 返回值:成功时返回指向新内存块的指针,失败时返回 NULL,且原内存块保持不变。


作用

  1. 调整内存大小

    • 扩大内存块:如果新的大小大于原大小,realloc 会尝试扩展内存块,保留原有数据。

    • 缩小内存块:如果新的大小小于原大小,realloc 会截断内存块,保留新大小范围内的数据。

  2. 重新分配内存

    • 如果原内存块无法扩展,realloc 会分配一个新的内存块,将原数据复制到新内存块中,并释放原内存块。

  3. 释放内存

    • 如果 size 为 0 且 ptr 不为 NULLrealloc 会释放原内存块,并返回 NULL

示例

#include <stdio.h>
#include <stdlib.h>

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;
}

优点

  1. 动态调整内存:可以根据需要动态调整内存大小,避免内存浪费。

  2. 保留数据:在扩展内存时,原有数据会被保留。

  3. 灵活性:适合处理动态变化的数据结构,如动态数组、链表等。


缺点

  1. 性能开销:如果无法在原内存块上扩展,realloc 需要分配新内存并复制数据,这会带来额外的性能开销。

  2. 内存碎片:频繁调整内存大小可能导致内存碎片。

  3. 潜在的内存泄漏:如果 realloc 失败并返回 NULL,原内存块不会被释放,可能导致内存泄漏。


注意事项

  1. 检查返回值realloc 可能失败,返回 NULL,因此需要检查返回值。

  2. 避免直接覆盖指针

ptr = realloc(ptr, new_size); // 错误:如果 realloc 失败,ptr 会丢失

正确做法:

void *new_ptr = realloc(ptr, new_size);
if (new_ptr == NULL) {
    // 处理错误
} else {
    ptr = new_ptr;
}
  1. 释放内存:使用 realloc 后,仍需使用 free 释放内存。

总结

  • realloc 是动态内存管理的重要工具,适合需要动态调整内存大小的场景。

  • 使用时需注意检查返回值,避免内存泄漏和性能问题。

  • 结合 malloccalloc 和 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/

相关文章:

  • 《全球网络安全政策法律发展研究报告 (2024) 》
  • 归并排序(C# C++)
  • 【分布式文件存储系统Minio】2024.12保姆级教程
  • LinkedList
  • Cherno C++ P55 宏
  • 什么是MVC?什么是SpringMVC?什么是三层架构?
  • 使用 Shiro 和 JPA 结合 MySQL 实现一个简易权限管理系统
  • scratch发射火箭 2024年12月scratch三级真题 中国电子学会 图形化编程 scratch三级真题和答案解析
  • DeepSeek 的开源优势:为什么选择它而不是其他闭源模型?
  • 人工智能 - 大脑神经网络与机器神经网络的区别
  • GitLab CI/CD 的配置详解:从零开始使用 .gitlab-ci.yml 文件
  • 10G EPON光模块
  • 深入解析 vLLM:高性能 LLM 服务框架的架构之美(一)原理与解析
  • CPP集群聊天服务器开发实践(五):nginx负载均衡配置
  • Field ‘id‘ doesn‘t have a default value
  • Redis 事物
  • React 第二十六节 <Profiler></Profiler> 的用途使用方法
  • 【零基础学Mysql】常用函数讲解,提升数据操作效率的利器
  • 2025年 Java 面试八股文
  • 鸿蒙Harmony-UIAbility内状态-LocalStorage详细介绍
  • 俄乌战火不熄,特朗普在梵蒂冈与泽连斯基会晤后口风突变
  • 瞄准“美丽健康”赛道,上海奉贤如何打造宜居宜业之城?
  • 我国首个大型通用光谱望远镜JUST在青海启动建设
  • 国家核安全局局长:我国核电进入大规模建设高峰期,在建规模超其他国家总和
  • 经济日报金观平:统筹国内经济工作和国际经贸斗争
  • 俄罗斯准备在没有先决条件的情况下与乌克兰进行谈判