没有躲过的坑--指针(内存泄露)

来源:互联网 发布:matlab数据转换 编辑:程序博客网 时间:2024/04/29 10:58

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。

1 0