动态内存管理

本文详细解析了C/C++程序的内存分布,包括内核空间、栈、堆、数据段、代码段和内存映射段的功能及用途。深入探讨了C/C++中的动态内存管理方式,如malloc、calloc、realloc、free与new、delete的操作细节及其对自定义类型的处理差异。
摘要由CSDN通过智能技术生成

C/C++内存分布:

内核空间是操作系统使用维护,用户不用对其进行管理。

栈又叫堆栈,非静态局部变量/函数参数/返回值等等

内存映射段,高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享内存,做进程间通信。

,用于程序运行时动态内存分配。

数据段,存储全局变量和静态数据。

代码段,可执行的代码/只读常量。

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

从堆上进行动态内存分配:

申请内存:

malloc:

void* malloc (size_t size);     

/*

用户所需内存空间大小的字节数;

不会对申请空间进行初始化。

*/

 

calloc :

void* calloc (size_t num, size_t size); // num-->申请元素个数

/*

会对申请成功的空间进行初始化--> 0;

*/


realloc:

void* realloc (void* ptr, size_t size); // ptr-->地址

/*

  ptr == NULL 那么realloc等价于malloc;

  ptr != NULL 对之前申请的空间进行调整,需要比较原空间和新空间大小。

                     如果缩小空间--> 返回原空间首地址;

                            扩大空间--> 扩大空间较少--> 返回原空间首地址

                                                扩大空间较多--> 开辟newsize大小的新空间;

                                                                           将旧空间元素拷贝到新空间;

                                                                           释放旧空间;

                                                                           返回新空间首地址。

*/

  相同点: 都需要用户通过 free释放;

                 返回类型为 void*,所以要对返回结果进行强制类型转化;

                 申请失败返回NULL;

                 为防止用户使用越界,会对用户申请的空间会在前后各添加4字节的保护机制;

                 为维护用户申请的空间,每段申请的空间,都会花费36字节去管理。

int main()
{
	int* p1 = (int *)malloc(sizeof(int)* 10);
	free(p1);
    
    return 0;
}

 

 

 

C++中动态内存管理方式:

空间的申请: new T /new T[ ]

int main()
{
    // new后跟所申请空间的类型
    int* p1 = new int;     // 可以不对申请的单个元素空间初始化
    int* p2 = new int(10); // 也可以初始化
    
    int* p3 = new int[10] ; // 申请一段连续空间,但不能对其初始化
    
    return 0;
}

 

                       new/new[]由于申请时已经给出其类型,所以之后不用进行类型转化;

 

空间的释放: delete add / delete[ ] add;

{
    delete p1;
    delete p2;
    delete[] p3;
}

 

                          <必须匹配使用>

针对内置类型:

                       malloc/new/new[]

                       free/delete/delete[]

                       可以不匹配使用,因为调用内置类型不用对其进行构造。

自定义类型:

                       malloc:不调用构造函数初始化空间,它只会动态开辟和对象大小相同的一段空间。

                       free:只负责释放空间。

                       new:将对象空间开辟成功,再调用构造函数完成空间初始化。

                       delete:先调用析构函数释放对象中的资源,在释放对象所占的空间。

class Test
{
public:
	Test(){
		cout << "Test():" << _ptr << endl;
		_ptr = new int;
	}
	
	~Test(){
		cout << "~Test():" << _ptr << endl;
		if (nullptr != _ptr){
			delete _ptr;
			_ptr = nullptr;
		}
	}
private:
	int* _ptr;
};

int main()
{
	Test* ptr1 = (Test*)malloc(sizeof(Test));   // 用malloc申请空间
	delete ptr1;                                // 用delete来释放
}

 

 因为malloc只能申请所需要的空间而不能构造对象,所以对象的成员变量为随机值,之后调用delete释放就使得程序崩溃。

 

  类似的如果用new申请空间,free释放空间:

     free只会释放对象的空间,但对象中的资源不会清理,这样就产生了内存泄漏。

  如果用new[]申请一段空间,而用delete释放空间:

    delete只释放一个单元空间,之后空间没办法释放程序崩溃。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值