一、内存泄露
1、delete销毁对象时,不会free掉成员变量申请的内存区域
(1)销毁对象时,如果析构函数没有释放成员变量指向的内存区域,则会造成内存泄露
(2)使用STL模板类,delete模板对象指针时,不会自动free模板类成员申请的内存区域
示例代码:
#include <iostream>
#include "stdlib.h"
#include <list>
using namespace std;
typedef struct STstudent{
char *name;
int number;
}student;
int main()
{
while (1){
list<student> *pList = new list<student>();
student Stu;
Stu.name = (char*)malloc(100);
Stu.number = 1234;
pList->push_back(Stu);
free(Stu.name); //如果不释放,会内存泄露
delete pList;
}
}
2、strdup内存泄露
strdup实现机制中,内部会使用malloc自动分配内存空间,并复制字符串,因此使用结束后,必须手动释放。
释放方式可以使用free或者delete,视平台而定,在有些平台下,使用free会造成进程崩溃。
因此,不建议使用strdup拷贝字符串,如果想做字符串复制操作,建议直接使用malloc函数加memcpy函数。
示例代码:
(1)使用strdup:
#include "stdlib.h"
#include "string.h"
int main(){
char *src = "hello";
char *des = NULL;;
des = (char*)strdup(src);
free(des);
//delete(des);
}
(2)使用malloc+memset+mmecpy:
注意:拷贝字符串的时候,malloc需要多分配一个字节,用于保存结束符'\0',否则后续当成字符串处理时,会出现错误。
#include "stdlib.h"
#include "string.h"
int main(){
char *src = "hello";
char *des = NULL;;
des = (char*)malloc(strlen(src) + 1);
memset(des, 0, strlen(src) + 1);
memcpy(des, src, strlen(src));
}
二、内存释放
//以下内容转载自:https://blog.csdn.net/u010319440/article/details/48034867
使用free释放内存时,程序崩溃原因总结:
1、释放一个空指针。
2、重复释放,所以释放一个指针之后,一般需要把指针置为空,以避免下次重复释放。
if(p!=NULL){
free(p);
p=NULL;
}
3、释放一个非自己申请的内存,或者释放的指针指向的地方不是本进程申请的。
比如主进程中调用dll,在dll中使用strdup申请内存,然后将指针传回给主进程,在主进程中释放该内存区域,会造成程序崩溃。
解决方案:在dll中再加一个方法,比如MemRelease,主程序调用这个方法来释放内存。
4、申请的内存块写过界了或者被写过界了,此时内存块就被破坏了,释放的时候为了避免释放掉其他有用的数据,会报错。
//以上内容转载自:https://blog.csdn.net/u010319440/article/details/48034867
5、malloc和free成对出现,new和delete成对出现,混合使用可能造成程序崩溃。
6、释放内存的起始地址不正确。
这种情况debug模式下会报错,release模式下不会报错,因此在release模式下极易造成内存泄露。
测试代码如下:
#include "stdlib.h"
int main(){
char *p = (char*)malloc(20);
p = p + 10;
free(p);
system("pause");
}