c++中的动态内存管理

1、内存:
说到内存管理,大多人都不了解什么是内存管理,下面我来简单介绍一下:
一般把内存理解为四部分:栈 、堆、静态区(数据段)、常量区(代码段)
存储内容:
:存放局部变量,栈上的内容只在函数作用域范围内有效,出了作用域会自动销毁,其存储特点是效率高但存储空间有限。

:由使用者动态开辟出来的空间存在堆上,如malloc、new,其生命周期由free和delete来决定,其特点是使用灵活,空间大但容易出错。

静态区: 全局变量和静态变量(static)的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放 。有编译器在编译的时候分配(数据段(存储全局数据和静态数据)和代码段(可执行的代码/只读常量))。
这里写图片描述
2、malloc 、calloc 、realloc:

malloc  
 

函数原型:(void*)malloc(unsigned size);(字节数)

malloc函数在内存中开辟的是一块连续的空间,size是所需要空间的长度,开辟的大小为size*参数类型,开辟完之后返回这块空间的首地址。

calloc  

函数原型:void* calloc(size_t numElements, size_t sizeOfElements);(元素的个数,
单个元素的字节数)

和malloc相似,它也是开辟一块连续的空间,空间的大小为:元素的个数*单个元素的字节数。

realloc  

函数原型:void* realloc(void* ptr, unsigned newsize);(地址,字节数)
给一个已经分配地址的指针重新分配空间,参数ptr为原有的空间指针,newsize为重新申请的地址长度。它与malloc的区别就是如果你给的指针是NULL,那么你使用的就是malloc,如果你给出的指针是一个已经分配了地址的指针(ptr),那么你使用的就是realloc。

区别:

(1)函数malloc不能初始化所分配的空间,而函数calloc能,也就是说,如果由malloc函数分配的空间原来没有被分配过,则其中每一位都可能是0;反之,如果这一块数据块原来被分配过,那里面可能遗留着各种各样的数据。所以,当你在使用malloc开辟一块新空间的时候,要重新初始化那一块空间(一般调用memset函数来初始化空间)。否则在多次释放、开辟之后,可能会出现使用错误。

(2)calloc函数会将所分配的内存空间中的每一位都初始化为0(这也是它和malloc的主要不同处之一)。也就是说,如果你是为字符类或者整形类的元素分配空间,那么这些元素会保证被初始化为0;如果你是为指针类函数分配内存,那么这些元素都会被初始化为空指针。

(3)malloc向系统申请size个字节的空间,申请完之后返回的是这个空间的首地址,类型为void*,而void*表示未确定的类型,在c/c++中void*可以被强转成任意类型的指针。

(4)realloc可以对给定的指针所指向的空间进行扩大或者缩小,无论是扩大还是缩小,原有内存中的内容将保持不变(如果对于缩小之后的空间,被缩小的那部分空间内的数据还是会丢失)。realloc并不保证调整后的内存空间和原来的内存空间保持同一个地址。相反,realloc指针很可能指向一个新的地址。

(5)realloc是从堆上分配空间的,但当你进行扩大的时候,realloc会试图从堆上现存的数据后面的那些字节中获取附加的字节,如果能满足,就刚好。但如果后面的字节数不够,其就会使用堆上第一个有足够大小的自由块,然后将现存的数据拷贝到新的位置,将老块放回到堆上。在这个过程中,数据会被移动。也就是说,当你使用realloc的时候,数据可能被移动。

3、内存释放

malloc和free是一一对应的,如果malloc两次但是只free一次就会存在内存泄漏,如果malloc一次但是free了两次,就会出错(第一次使用free的时候,malloc所开辟的空间就已经被释放,第二次使用free就无内存空间可以释放了,这种对内存的误操作就有可能会导致程序的崩溃)。

内存释放完毕一定要将指针置为空指针(否则会出现野指针)

4、new/delete

C++通过new和delete动态管理内存。
new/delete动态管理对象。
注意malloc/free、new/delete、new[]/delete[]
一定匹配使用,一定匹配使用,一定匹配使用!!!重要的事说三遍!否则可能出现内存泄露甚至崩溃的问题
这里写图片描述

5、【malloc/free和new/delete的区别和联系?】

  1. 它们都是动态管理内存的入口。
  2. malloc/free是C/C++标准库的函数,new/delete是C++操作符。
  3. malloc/free只是动态分配内存空间/释放空间。而new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(清理
    成员)。
  4. malloc/free需要手动计算类型大小且返回值会void*,new/delete可自己计算类型的大小,返回对应类型的指针。

6、总结:
1. operator new/operator delete operator new[]/operator delete[] 和 malloc/free用法一样。
2. 他们只负责分配空间/释放空间,不会调用对象构造函数/析构函数来初始化/清理对象。
3. 实际operator new和operator delete只是malloc和free的一层封装。
new做了两件事
1. 调用operator new分配空间。
2. 调用构造函数初始化对象。
delete也做了两件事
1. 调用析构函数清理对象
2. 调用operator delete释放空间
new[N]
1. 调用operator new分配空间。
2. 调用N次构造函数分别初始化每个对象。
delete[]
1. 调用N次析构函数清理对象。(思考这里怎么N是怎么来的?)
2. 调用operator delete释放空间。
图解:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/adzn1/article/details/79795119