在C语言中,使用malloc/calloc/realloc/free进行动态内存管理,malloc/calloc/realloc用来在堆上开辟空间,free将申请到的空间释放掉。malloc只能开辟空间,不会初始化;calloc会进行初始化;realloc当首个参数为空指针时等价于malloc,其次,也可以扩容。realloc可以改变原有内存的大小,若不能改变,则将会开辟一段新的空间,将原有内存的内容拷贝过去,但不会对新开辟的空间进行初始化。 使用_alloc在栈上动态开辟内存,栈上开辟的内存由编译器自动维护,不需要用户显示释放。
堆上的内存需要用户自己来管理,动态malloc/calloc/realloc的空间必须free 掉,否则会造成内存泄漏;栈上的空间具有函数作用域,在函数结束后系统自动回收,不用用户管理。 1.栈又叫堆栈,非静态局部变量/函数参数/返回值等等,栈是向下增长的 2.内存映射是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可以使用系统接口创建共享内存,做进程间通信。 3.堆用于程序运行时动态内存分配,堆是可以上增长的。 4.数据段—-存储全局数据和静态数据 5.代码段—-可执行的代码/只读常量。
(1)内存申请了忘记释放
int *pTest =(int *)malloc(10*sizeof(int)); assert(NULL != pTest); DoSomething();(2)程序逻辑不清,以为释放了,实际内存泄漏
int *pTest1 = (int *)malloc(10*sizeof(int)); int *pTest2 = (int *)malloc(10*sizeof(int)); Dosomething(); pTest1 = pTest2; free(pTest1); free(pTest2);(3)程序误操作,将堆破坏
char *pTest3 = (char*)malloc(5); strcpy(pTest3,"Memory Leaks!"); free(pTest3);(4)释放时传入的地址和申请时的地方不相同
int *pTest4 = (int *)malloc(10*sizeof(int)); assert(NULL != pTest4); pTest4[0] = 0; pTest4++; DoSomething(); free(PTest4);C++通过new和delete运算符进行动态内存管理。 注:new和delete、new[ ]和delete[ ]一定要匹配使用,一定要匹配使用,一定要匹配使用!!!否则会出现内存泄漏甚至崩溃的问题。
malloc和free只管开辟空间,而new和delete还会调用自定义类型(创建出来就被初始化了)的构造函数和析构函数。new—>先开辟,再调用构造;delete—>先析构,在释放。
malloc / free / 和new / delete的区别联系: (1)它们都是动态内存的入口 (2)malloc / free 是C/C++标准库的函数,new / delete是C++操作符。 (3)malloc / free只是动态分配内存空间 / 释放空间。而new / delete 除了会分配空间还会调用析构函数进行初始化与清理(清理成员) (4)malloc / free需要手动计算类型的大小且返回值void*,new / delete可以自己计算类型的大小,返回对应类型的指针。malloc失败会返回0,new会抛出异常。
C++的其他内存接口: void * operator new(size_t size); void * operator delete(size_t size); void * operator new [](size_t size); void * operator delete [](size_t size); 标准库函数operator new和operator delete的命名容易让人误解。与其他operator函数(operator=)不同。这些函数没有重载new和delete表达式。实际上,我们不能重定义new和delete表达式的行为。 通过调用operator new函数执行new表达式获得内存,并接着在该内存中构造一个对象,通过撤销一个对象执行delete表达式,并接着调用operator delete函数,以释放该对象使用的内存。 总结: 1. operator new/operator new []/operator delete和operator delete []和malloc/free一样。 2. 他们只负责分配空间/释放空间,不会调用对象构造函数/析构函数来初始化/清理对象。 3. 实际operator new和operator delete只是malloc和free的一层封装。 【new作用】 调用operator new 分配空间。 调用构造函数初始化对象。 【delete作用】 调用析构函数清理对象。 调用operator delete释放空间。 【new []作用】 调用operator new 分配空间。 调用N次构造函数分别初始化每个对象。 【delete作用】 调用N次析构函数清理对象。 调用operator delete释放空间。
