动态内存分配(C/C++), 含有malloc和calloc使用例子

本文介绍了C/C++程序中的内存分配区域,包括栈区、堆区和静态区,重点讲解了malloc、free和calloc动态内存分配函数的使用,以及常见的内存分配错误。最后提到了柔性数组的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态内存分配(C/C++)

1. C/C++程序内存分配的几个区域

  • 栈区 (stack): 在执行程序时, 函数内局部变量的存储单元都可以创建在栈上, 函数执行结束时这些存储单元自动被释放. 栈内存的分配运算内置于处理的指令集中, 效率高, 但是分配的内存容量有限.

  • 堆区(heap): 由程序员自己分配和释放, 分配方式类似于链表. 如果程序员没有释放, 程序结束时可能由os回收.

  • 静态区(static): 存放全局变量, 静态数据. 程序结束后由系统释放.
    在这里插入图片描述

2. 动态内存分配的常用函数

2.1 malloc和free

int main()
{
	int* p = (int*)malloc(10 * sizeof(int));    //开辟十个int大小的堆区空间
	if (p == NULL) {
		printf("%s\n", strerror(errno));
	}
	else {
		printf("%s\n%s", "complete", "yeah");
		for (int i = 0; i < 10; i++)
		{
			*(p + i) = i;
			printf("%d  ", *(p + i));
		}
	}
	// 当申请的动态空间不使用时,应该还给操作系统
	// 鼓励主动释放
	free(p);
	p = NULL;
	return 0;
}

2.2 calloc

int main()
{
	// calloc 每个元素默认值为0
	int* p = (int*)calloc(10, sizeof(int));
	//int* p = (int*)malloc(40);
	cout << "第一次开辟的地址:" << p << endl;
	if (p == NULL) {
		cout << "开辟失败" << endl;
		return 1;
		//printf("%s\n", strerror(errno));
	}
	else
	{
		printf("%s\n%s\n", "complete", "yeah");
		for (int i = 0; i < 10; i++)
		{
			*(p + i) = i;
			printf("%d  ", *(p + i));
		}
	}
	cout << endl;	
	
	//假如四十个字节不能满足需求了,再开辟四十个
	//此时需要弄一个临时指针 
	int new_number = 11;
	//用新定义的指针来管理
	int* ptr = (int*)realloc(p, new_number*sizeof(int));

	if (ptr == NULL)
	{
		// 追加失败
		cout << "追加内存失败" << endl;
		return 2;
	}
	else {
		p = ptr;
		cout << "第二次开辟的空间:" << p << "   临时地址:" << ptr << endl;

		int i = 0;
		for (i = 0; i < new_number; i++)
		{
			//*(p2 + i) = i;
			printf("%d  ", *(p + i));
		}
	}
	cout << endl;
	free(p);
	p = NULL;
	cout << *ptr << endl;
	return 0;
}

3. 动态内存分配的常见错误

  • 对空指针NULL进行解引用操作

  • 对开辟的空间进行越界操作

  • 用free函数释放非动态空间的内存

  • 使用free只释放了动态空间的一部分

补充: 柔性数组

定义: 结构体当中最后一个元素允许时未知大小的数组, 此时该元素(成员)被称为’柔性数组’成员.

struct Student {
	int age;
	int arr[];	    //在结构体当中,此时可以是未知大小的,这个就是柔性数组
	//int arr[0];	//  第二种表示方法
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值