一、野指针
#include<iostream>
#include<malloc.h>
using namespace std;
int main()
{
int *p = NULL;
p = (int*)malloc(sizeof(int));
*p = 4;
free(p);
printf("%d\n",p);
if(p != NULL)
{
printf("%d\n",*p);
}
return 0;
}
运行结果如下
程序中p指向一块动态分配的内存,并给p所指的内存赋值,随后调用free释放动态分配的内存。在随后的判断中p却不为空,但是p所指内存空间的值却不是4。假设动态分配的内存区域为A。p和A是在不同的内存块中,p所有内存单元存放的是A的首地址。如下图所示
调用free()函数释放的是p所指的内存区域,即内存区域A的内容。但是对于p却没有任何改变,p中依然存放着原来内存区域A的首地址。所以上面的程序中虽然调用了free却仍然能够访问原来的内存空间,只不过打印出来的数据是“脏”数据而不是4。所谓的野指针,就是指针p所指的内存空间已经被free掉,但p还指向原来的内存空间。假设p中存放的是用户账户余额,在free后又需要用到该值,若使用if(p != NULL)进行判断后果绝对很严重。避免野指针的方法就是在free后将p设置为NULL(p = NULL)。
二、指针与数组
大多数时候指针可以当成数组一样使用
#include<iostream>
using namespace std;
int main()
{
char s1[] = "abc";
char *p = s1;
cout<<s1[0]<<p[1]<<endl;
return 0;
}
程序编译运行没有任何问题
但是有些时候指针不能像数组一样使用
#include<iostream>
using namespace std;
int main()
{
char s1[] = "abc";
char *p = "abc";
s1[0] = 'A';
p[0] ='A';//编译没有问题,运行时错误
return 0;
}
上面程序中定义了一个字符数组并初始化为"abc",另外定义了一个指针p指向字符串"abc"。char s1[]="abc"是在栈区分配一块内存区域,并将其值初始化为"abc"。而char *p = "abc",由于“abc"是字符串常量,所以先在静态内存区域中分配一块区域,p指向该内存区域。由于"abc"是一常量。所以调用p[0] = 'A'会导致访问内存错误。在这里p[0] = 'A'的错误并不是由于"abc"放在静态区域,之所以错误是由于"abc"是字符串常量。另外静态分配的内存在整个程序的运行期间会一直存在。
三、尚未搞懂的指针问题
#include<iostream>
using namespace std;
class A
{
public:
void print()
{
cout<<"Class A"<<endl;
}
void setData(int d)
{
data = d;
}
private:
int data;
};
int main()
{
A *p = NULL;
cout<<sizeof(p)<<endl;
p->print();
//p->setData(123);//发生内存错误
return 0;
}
在main函数中定义了一个类A的指针p并将其设置为NULL,sizeof(p)的大小为4。但是上面的程序中竟然能够成功的调用类A的方法。要知道上面的程序中p的内存空间中存放的是NULL。但是若中A的print()方法中加入cout<<data<<endl或在main()中加入p->setData(123)就会报访问内存错误。实在无法解释上面程序中的现象。在高质量C++编程指南一书作者说可能是由于编译器的原因,但目前我在vc++6.0,vs2008,dev c++平台下运行现象都一样。目前还未在linux下进行测试。
1763

被折叠的 条评论
为什么被折叠?



