内存管理(一):申请内存空间使用

前言

侯捷老师内存管理视频的讲解的C++内存分配的每一层面如下:

在这里插入图片描述

四个层面的基本用法

(1)malloc / free

malloc / free 申请(释放)内存的语法比较简单

	void* p1 = malloc(512);	// 分配512 bytes
    if (p1 != nullptr)
        cout << "malloc allocate successfully!" << endl;
    // int* p = (int*)malloc(sizeof(int)*128);  // 分配128个int型空间
     free(p1);
     p1 = nullptr;

(2)new / delete

new / delete 在堆区开辟空间(释放),注意其内部调用的依然是 malloc / free

	complex<int> * p2 = new complex<int>; // 申请创建one object
	if (p2 != nullptr)
        cout << "new allocate successfully!" << endl;
    delete p2;
    p2 = nullptr;

(3)operator new / operator delete

operator new / operator delete函数可以进行重载,若使用的是全局的,需要加上作用域 ::,其内部调用的依然是 malloc / free

	void* p3 = ::operator new(512); //512 bytes
	if (p3 != nullptr)
        cout << "::operator new allocate successfully!" << endl;
    ::operator delete(p3);
    p3 = nullptr;

(4)C++ 标准库提供的 allocators

其接口虽有标准规格,但实现厂商并未完全遵守;下面三者形式略异。

#ifdef _MSC_VER
		 //以下两函数都是 non-static,一定要通过 object 调用。以下分配 3 个 ints.
        int* p4 = allocator<int>().allocate(3, (int*)0);
        if (p4 != nullptr)
            cout << "allocator<int>() allocate successfully!" << endl;
        allocator<int>().deallocate(p4, 3);
#endif
#ifdef __BORLANDC__
 		//以下两函数都是 non-static,一定要通过 object 调用以下分配 5 个 ints.
        int* p4 = allocator<int>().allocate(5);
        allocator<int>().deallocate(p4, 5);
#endif
#ifdef __GNUC__
        //以下两函数都是 static,可通过全名调用之。以下分配 512 bytes.
        //void* p4 = alloc::allocate(512); 
        //alloc::deallocate(p4,512);   

        //以下两函数都是 non-static,一定要通过 object 调用以下分配 7 个 ints.
        void* p4 = allocator<int>().allocate(7);
        allocator<int>().deallocate((int*)p4, 7);

        //以下两函数都是 non-static,一定要通过 object 调用以下分配 9 个 ints.	
        void* p5 = __gnu_cxx::__pool_alloc<int>().allocate(9);
        __gnu_cxx::__pool_alloc<int>().deallocate((int*)p5, 9);
#endif

输出结果

在这里插入图片描述


new / delete expression

C++中代用new在堆区创建对象,其实经历了以下步骤:1. 开辟空间;2. 类型转换;3. 调用构造函数;4 指针指向创建的对象。 同样地,delete释放对象的步骤:1. 调用析构函数;2 释放内存。

#include<iostream>
class A
{
public:
	A(int Id = 0):id(Id)
	{
		std::cout << "ctor.this = " << this << " id = " <<id << std::endl;
	}
	~A(){std::cout << "dtor.this=" << this << " id=" << id << std::endl;  } 
public:
	int id;
};

int main()

{
	// 正常创建一个类对象
	A* p = new A(1);
	std::cout <<"p->id = "<< p->id << std::endl; // id = 1
	// p->A::A(3); // in VC6可以通过调用ctor;in GCC 错误,不能调用ctor
	delete p;

	std::cout << std::endl;

	//simulate: A* p = new A(2)
	void* mem = ::operator new(sizeof(A)); // 1 allocate
	std::cout << "mem =" << mem << std::endl; 
	p = static_cast<A*>(mem);              // 2 cast
	std::cout << "p = "<< p << std::endl;
	p->A::A(2);                      // 3 调用construct,并指向该对象

	std::cout << std::endl;

	//simulate delete p
	p->~A();	// 1 调用析构函数				
	::operator delete(p);  // 2 释放内存	

	system("pause");

	return 0;
}

在simulate A* p = new A(2)delete p的过程中,我们使用了::operator new::operator delete这里因为这两个是可以重载的,我们使用::表示我们使用的是全局的,也就是系统给我们提供的原始operator new、operator delete

输出结果

在这里插入图片描述
这里 构造函数 不可以被直接调用,例如在 p->A::A(3); // in VC6可以通过调用ctor;in GCC 错误,不能调用ctor,而 p->~A();却可以直接调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值