C++中的5中内存分配方式:栈、堆(new)、自由存储区(malloc)、全局/静态存储区、常量存储区

C++程序中有内存分为5个区:
(1) 栈
(2) 堆
(3) 自由存储区
(4) 全局/静态存储区
(5) 常量存储区


(1) 栈:
栈(stack)是一个线性表,具有线性关系。在数据结构中,栈类似一个“弹夹”,即:弹夹中的子弹先进去,而要后出来,后进去,就先出来。
栈是限定仅在表尾进行插入和删除操作的线性表。且允许插入和删除操作的一段为栈顶(top),栈又称为Last in Frist Out(后进先出),即:LIFO结构。
栈的插入操作:称为进栈、压栈、入栈等。
栈的删除操作:称为出栈、弹栈等。
(2) 堆:
堆区的内存和释放由“开发者”负责。
一般是用运算符“new”来分配内存,并用“delete”释放内存。一个“new”要对应一个“delete”,否则容易发生“内存泄漏”。
缺点:
当使用new动态分配数组长度时,不能“显式”提供“初始化值”。

动态内存分配语法规则:
a.为变量分配内存:

类型标识符 *指针名 = new 类型标识符(初始值);

其中:初始值可省略
例如:

int  *p =new int(3)
int  *p =new int;

b.为数组分配内存:

类型标识符 *指针名 = new 类型标识符[数组长度];

其中:数组长度是由“[]”括起来
例如:

int  *p =new int[3];

当数组长度不确定时,还可以动态创建一个数组:

int n=3;
int  *p =new int(n);

或者:

int *length=new int;
cin>>*length;
int *p=new int[*length];

动态内存释放语法规则:
a.对于变量:

delete 指针名;

b.对于数组:

delete []指针名;

例如:

delete p;
delete []a;

(3) 自由存储区
在自由存储区,其内存管理是通过库函数malloc和free进行的。
malloc的全称是memory allocation,中文叫动态内存分配。
要添加的头文件

#include <stdlib.h>

或者:

#include <malloc.h>

它的函数原型是:

extern void *malloc(unsigned int num_bytes);

说明:
a.分配长度为num_bytes字节的内存块。如果分配成功则返回指向被分配内存的指针,分配失败返回空指针NULL。
b.void* 表示未确定类型的指针,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者…)。
c.C/C++规定,void* 类型可以强制转换为任何其它类型的指针。
d.申请了内存空间后,必须检查是否分配成功。
e.当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。
f.malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的

malloc函数的使用:
语法规则为:

类型标识符 *指针名 = (类型标识符*)malloc(sizeof(类型标识符));

说明:
malloc 函数返回的是 void * 类型,对于C++,如果你写成:

int *p = malloc (sizeof(int));//错误语法,不能将 void* 赋值给 int * 类型变量

程序无法通过编译,必须通过 (int *) 来将强制转换。
而对于C,没有这个要求,但为了使C程序更方便的移植到C++中来,建议养成强制转换的习惯。
例如:

int *p;
p = (int*)malloc(sizeof(int) * 10);
//分配10个(可根据实际需要替换该数值)整型存储单元,
//并将这10个连续的整型存储单元的首地址存储到指针变量p中

申请了动态内存后,必须检查是否分配成功:
例如:

int *p;
if(NULL == (p = (int*)malloc(sizeof(int))))
//请使用if来判断,这是有必要的
{
    perror("error...");
    exit(1);
}

最后要释放内存:
例如:

free(p);
p = NULL;//请加上这句

例子:使用malloc分配动态内存来写的冒泡排序算法
程序为:

#include<stdio.h>
#include "malloc.h"
#include <iostream>
using namespace std;
void pop(int *array, int num)
{
	int i, j, temp;
	for (i = 0; i<num; i++)
		for (j = 0; j<num - i - 1; j++)
		{
		if (*(array + j)>*(array + j + 1))
		{
			temp = *(array + j);
			*(array + j) = *(array + j + 1);
			*(array + j + 1) = temp;
		}
		}

}
int main()
{
	int num , i;
	printf("how much number you need:");
	scanf_s("%d", &num);
	int *array = (int *)malloc(num*sizeof(int));
	if (NULL == array)
	{
		cout << "动态内存分配出错" << endl;
	}
	for (i = 0; i<num; i++)
	{
		//array[i] = 2*i - 1;
		scanf_s("%d", &array[i]);
	}
	pop(array, num);
	for (i = 0; i<num; i++)
		printf("%d ", *(array + i));
	printf("\n");
	free(array);
	array = NULL;
	return 0;
}

输出结果为:
在这里插入图片描述
(4) 全局/静态存储区
全局/静态存储区,存放的是全局变量和静态变量。该存储区在整个程序运行期间一直有效,直到程序结束,系统才回收。
(5) 常量存储区
这个区存储的是常量,通常不允许修改。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CSU_hhxyliang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值