C/C++ 内存管理(关于new和delete的实现原理)

47 篇文章 0 订阅

C++中,进程分为代码段,数据段,堆,内存映射段,栈,内核空间,其中,栈空间大小为8M,堆空间大小为2G(在32位平台下)
栈又叫堆栈,函数调用会建立栈桢,存储局部变量/形参/返回值等等,栈是向下增长的(高地址向低地址使用)。
内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。
堆用于程序运行时动态内存分配,堆是向上增长的。

int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
 static int staticVar = 1;
 int localVar = 1;
 
 int num1[10] = {1, 2, 3, 4};
 char char2[] = "abcd";
 const char* pChar3 = "abcd";
 int* ptr1 = (int*)malloc(sizeof (int)*4);
 int* ptr2 = (int*)calloc(4, sizeof(int));
 int* ptr3 = (int*)realloc(ptr2, sizeof(int)*4);
 free (ptr1);
 free (ptr3);
}

其中关于malloc | free | calloc | realloc的使用规范如下:
静态内存开辟方式:

int a = 0;//4byte
int arr[10] = { 0 };//40byte 

通过定义栈上的临时变量,在定义变量时,需要指定变量的大小,但是对于静态内存在编译阶段不适用,有些大小预先不知道,需要代码编译阶段才会知道,因此引入了动态内存

malloc和free

#include<stdlib.h>
void* malloc (size_t size);

int* ptr = (int*)malloc(10 * sizeof(int));

说明:void*:这块内存是为谁申请的也不知道,返回什么类型也不合适,那就返回通用类型。
size:要申请的字节数
在堆区上申请size个字节的空间,并返回堆区上的起始地址。
函数返回值:

若开辟成功,返回一个指向开辟好空间的指针;
若开辟失败,则返回空指针NULL。
因此,malloc的返回值一定一定要做检查!!!

free

与malloc对应的是free,主要功能是对malloc动态开辟的空间进行内存的释放和回收

#include<stdlib.h>
void free(void* ptr);

函数功能:
功能:把ptr所指向的空间还给操作系统

  1. 若参数ptr指向的空间不是动态开辟的,则free函数的行为是标准未定义的。
  2. 若参数ptr是NULL空指针,即free(NULL);okay,只不过什么都不干。
    陷阱:
#include<stdio.h>
#include<stdlib.h>

int main()
{
	//申请空间
	int* p = (int*)malloc(10 * sizeof(int));
	if (p == NULL)
	{
		return -1;
	}
	//使用
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		*(p + i) = i;
	}
	//释放ptr指向的这段内存
	free(p);
	//p = NULL;//是否有必要?
	return 0;
}

首先:经过malloc函数申请内存空间后,会将ptr指向内存中开辟的空间,而后操作该部分内容,
其次:free函数的作用是释放申请的空间,但是并不会将ptr的内容置空
最后:由于ptr的值没有置空,指向还是之前的区域,会导致后面出现野指针,对该区域非法访问
一定要ptr == NULL;,让ptr永远也找不到这段空间

calloc

#include<stdlib.h>
void* calloc (size_t num, size_t size);

函数功能:
void*:空类型,为了适应各种指针类型,以便正确解引用
num:要申请的元素个数
size:元素大小
功能:为大小为size的num个元素开辟一块空间,并将每一个字节都初始化为0.
若开辟成功,则返回开辟好空间的起始地址
若开辟失败,则返回空指针NULL
因此,与malloc一样,对于calloc的返回值也一定一定要做检查!!!

对比malloc和calloc:
malloc:只负责在堆区申请空间,并返回起始地址,不会初始化空间
calloc:在堆区申请空间,初始化为0,并返回起始地址

realloc

#include<stdio.h>
void* realloc (void* ptr, size_t size);

ptr:要调整的内存地址
size:调整后的新大小
void*:调整后的内存起始地址
函数既可以进行扩容也可以减少容量,当内存不够大进行扩容时,函数在调整原内存空间大小的同时,还会将原内存中的数据移动到新的空间中去

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值