指针(内存泄露)
最后更新于:2022-04-01 06:40:00
##没有躲过的坑--指针(内存泄露)
C++被人骂娘最多的就是指针。
夜深人静的时候,拿出几个使用指针容易出现的坑儿。可能我的语言描述有些让人费劲,尽量用代码说话。
**通过指向类的NULL指针调用类的成员函数**
试图用一个null指针调用类的成员函数,导致崩溃:
~~~
#include <iostream>
using namespace std;
class A
{
int value;
public:
void dumb() const {cout << "dumb()\n";}
void set(int x) {cout << "set()\n"; value=x;}
int get() const {cout << "get()\n"; return value;}
};
int main()
{
A *pA1 = new A;
A *pA2 = NULL;
pA1->dumb();
pA1->set(10);
pA1->get();
pA2->dumb();
pA2->set(20);//崩溃
pA2->get();
return 0;
}
~~~
为什么会这样?
通过非法指针调用函数,就相当于给函数传递了一个指向函数的非法指针!
但是为什么pA2->dumb()会成功呢?
因为导致崩溃的是访问了成员变量!!
**使用已经释放的指针**
~~~
struct X
{
int data;
};
int foo()
{
struct X *pX;
pX = (struct X *) malloc(sizeof (struct X));
pX->data = 10;
free(pX);
...
return pX->data;
}
~~~
**使用未初始化的指针**
如果你这样写,编译器会提示你使用了未初始化的变量p。
~~~
void fooA()
{
int *p;
*p = 100;
}
~~~
那么如果我释放一个初始化的指针呢?
~~~
void fooB()
{
int *p;
free(p);
}
~~~
结果是一样的!!
**释放已经释放的指针**
直接看看代码:
~~~
void fooA()
{
char *p;
p = (char *)malloc(100);
cout << "free(p)\n";
free(p);
cout << "free(p)\n";
free(p);
}
~~~
这样的问题也许不会立即使你的程序崩溃,那样后果更加严重!!
**没有调用子类的析构函数**
之前的博客讲过,父类的析构函数最好声明为虚!!
~~~
ParentClass *pObj = new ChildClass;
...
delete pObj;
~~~
上述代码会造成崩溃,如果父类的析构函数不声明为虚,那么不会调用继承类的析构函数,造成内存泄露。
**内存溢出**
当我们拷贝字符串的时候,我们常常会用到 memcpy函数。这里特别需要注意的就是字符串结尾的null字符:
~~~
char *p = (char *)malloc(strlen(str));
strcpy(p, str);
~~~
为了躲过这个坑,只需要把 strlen(str) 改为 strlen(str)+1。