标签:c++
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。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:c++
原文地址:http://blog.csdn.net/wangshubo1989/article/details/49647919