快捷搜索: 王者荣耀 脱发

C/C++:动态内存管理方式的区别


C语言中动态内存管理方式

malloc/calloc/realloc和free

代码示例

void Test () {
          
   
    int* p1 = (int*)malloc(sizeof(int));
    free(p1);
    
  	// 1.malloc/calloc/realloc的区别是什么?
	int* p2 = (int*)calloc(4, sizeof (int)); 
	int* p3 = (int*)realloc(p2, sizeof(int)*10);
	
	// 2.这里需要free(p2)吗?
	free(p3); 
}

1. malloc/calloc/realloc的区别是什么?

解答:

void * malloc(size_t);	// 要申请空间的字节数
void * calloc(size_t, size_t);	// 第一个参数申请的元素个数;第二个参数是单个元素类型的大小
void * realloc(void *, size_t);
void * free(void *);
  1. malloc 开辟空间不会进行初始化
  2. calloc 会初始化空间为0
  3. realloc 是将 p 指向的空间调整到 size 的字节(当第一个参数传入NULL的时候和malloc一样)

假设:p 指向的空间原来的大小为 oldsize 字节

    size <= oldsize:需要将 p 指向的空间缩小到 size 字节(返回的还是原来空间的地址) size > oldsize:需要将 p 指向的空间扩增到 size 个字节。 p 之后没有被使用的空间足以支持本次扩增,返回 p 原来空间的手地址 p 之后没有被使用的空间不足以支持本次扩增 开辟新空间 拷贝元素 释放旧空间 返回新空间

2.这里需要free(p2)吗?

解答:

这里不需要free(p2);

realloc的操作步骤如下:

  1. 申请size个字节的空间
  2. 将 p 中的值拷贝到刚申请的空间中
  3. 释放 p,返回刚申请的空间

C++动态内存管理方式

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

new/delete操作内置类型

void Test() {
          
   
	// 动态申请一个int类型的空间 
	int* ptr4 = new int;
	// 动态申请一个int类型的空间并初始化为10 
	int* ptr5 = new int(10);
	// 动态申请3个int类型的空间 
	int* ptr6 = new int[3];
	
    delete ptr4;
    delete ptr5;
    delete[] ptr6;
}

注意:

    申请和释放单个元素的空间,使用new和delete操作符 申请和释放连续的空间,使用new[]和 delete[]

new和delete操作自定义类型

class Test
{
          
   
public:
    Test()
        : _data(0)
    {
          
   
        cout<<"Test():"<<this<<endl;
	}
	~Test() {
          
   
        cout<<"~Test():"<<this<<endl;
    }
private:
    int _data;
};

void Test2()
{
          
   
	// 申请单个Test类型的空间
	Test* p1 = (Test*)malloc(sizeof(Test)); 
	free(p1);
	
	// 申请10个Test类型的空间
	Test* p2 = (Test*)malloc(sizoef(Test) * 10);
	free(p2);
}

void Test2()
{
          
   
	// 申请单个Test类型的对象 
	Test* p1 = new Test; 
	delete p1;
	
	// 申请10个Test类型的对象 
	Test* p2 = new Test[10]; 
	delete[] p2;
}

注意:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。 所以在给类分配空间时,最好使用new/delete

知识点习题

  1. malloc函数进行内存分配是在什么阶段?

A. 编译阶段 B. 链接阶段 C. 装载阶段 D. 执行阶段

正确答案

D

答案解析

程序占用三种类型的内存:静态内存、栈内存、堆内存;

    静态内存:

用来保存局部static对象、类static数据成员以及定义在任何函数之外的变量

    栈内存:

用来保存定义在函数内的非static对象。 分配在静态内存或栈内存中的对象由编译器自动创建和销毁。对于栈对象,仅在其定义的程序块运行时才存在;static对象在使用之前分配,在程序结束时销毁。

    堆内存:

在程序运行时分配。动态对象的生存周期由程序(用户)来控制。

经验分享 程序员 微信小程序 职场和发展