C++学习笔记之指针

一、野指针

#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下进行测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值