[转]C/C++野指针

一、 莫名的恐惧感
对于指针确实有种莫名的恐惧感,从刚开始学习的时候就被老师灌输的概念是指针功能很强大,但是用得不够好,会有很大的副作用。什么叫用得够好?初学者谁都不会用,那且不是都不能用了?如果都这样,指针都没人用了,还要指针做什么?
陷入了上述困局的原因在于我们的这种莫名的恐惧感,指针如此之神秘,以至于如我一样大多数的人都望而生畏,无所适从,被迫放弃。

二、野指针
诚如当初老师的忠告一样, 指针是个很强大的工具,可是正因为它太强大,所以要操作它不是件易事。操作不当造成的野指针,甚至会引起系统死机等比较严重的后果。
如果程序定义了一个指针,就必须要立即让它指向一个我们设定的空间或者把它设为NULL,如果没有这么做,那么这个指针里的内容是不可预知的,即不知道它 指向内存中的哪个空间(即野指针),它有可能指向的是一个空白的内存区域,可能指向的是已经受保护的区域,甚至可能指向系统的关键内存,如果是那样就糟 了,也许我们后面不小心对指针进行操作就有可能让系统出现紊乱,死机了。所以我们必须设定一个空间让指针指向它,或者把指针设为NULL,这是怎么样的一 个原理呢,如果是建立一个与指针相同类型的空间,实际上是在内存中的空白区域中开辟了这么一个受保护的内存空间,然后用指针来指向它,那么指针里的地址就 是这个受保护空间的地址了,而不是不可预知的啦,然后我们就可以通过指针对这个空间进行相应的操作了;如果我们把指针设为NULL,我们在头文件定义中的 #define NULL 0 可以知道,其实NULL就是表示0,那么我们让指针=NULL,实际上就是让指针=0,如此,指针里的地址(机器数)就被初始化为0了,而内存中地址为0 的内存空间……不用多说也能想象吧,这个地址是特定的,那么也就不是不可预知的在内存中乱指一气的野指针了。

还应该注意的是,free和delete只是把指针所指的 内存给释放掉,但并没有把指针本身干掉。指针p被free以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,p成了“野指针”。如果此时不 把p设置为NULL,会让人误以为p是个合法的指针。用free或delete释放了内存之后,就应立即将指针设置为NULL,防止产生“野指针”。内存 被释放了,并不表示指针会消亡或者成了NULL指针。(而且,指针消亡了,也并不表示它所指的内存会被自动释放。)
三 例说野指针
例子1:
首先请诸位看以下一段“危险”的C++代码:

void function( void )  
{  
    char* str = new char[100];  
    delete[] str;  
    // Do something  
    strcpy( str, "Dangerous!!" );  
}       
    之所以说其危险,是因为这是一段完全合乎语法的代码,编译的时候完美得一点错误也不会有,然而当运行到strcpy一句的时候,问题就会出现,因为在这之 前,str的空间已经被delete掉了,所以strcpy当然不会成功。对于这种类似的情况,在林锐博士的书中有过介绍,称其为“野指针”。

例子2:——指针初始化引出的问题
对指针初始化时,引出的应该注意的问题小结:
(1)先看例子:

include

void main()
{
char p,p1="hello first!";
while((*(p++) = *(p1++)) != 0);

cout<
}
错处:
p定义时没有初始化,p是指向不定,是一个野指针。
p++可能引用得空间为非法的。
编译时不会出错,但运行时会造成程序崩溃。
(2)把上面的p初始化为NULL

include

void main()
{
char p=NULL,p1="hello first!";
while((*(p++) = *(p1++)) != 0);

cout<
}
也错:
NULL表示没有任何指向。p++没有任何意义,运行时会造成程序崩溃。这里就应该想到不能对NULL的指针进行直接操作。
(3)现在为p初始化为" ":
void main()
{
char p=" ",p1="hello first!";

while((*(p++) = *(p1++)) != 0);

cout<
}
还错:
p指向的是一个const常量的内容,可以通过*(p++)形式引用该值,但是不能改变它指向const的内容。
(4)

include

include

void main()
{
char c[]="";
char p=c,p1="hello first!";
char p_start=p;
while((
(p++) = *(p1++)) != 0);

cout<
}
问题:
此时数组是一系列的变量了,也就是p一有指向,二不是指向常量的而是指向变量的。所以按理应该行的。问题出在c太小,造成了数组越界,所以错掉!把c的大小改来不比"hello first!"小就行了。
5)对于的就想到用new来初始化了:

include

include

void main()
{
char p,p1="hello first!";
p=new char;
char p_start=p;
while((
(p++) = *(p1++)) != 0);

cout<
}
现在就可以了,哈,不过,我认为在new时最好还是把它的大小给指出来,如new char[strlen(p1)+1];如果不指定大小,我想p++会指向一些已用得地址,而这些地址又不能随便改,就会造成诸如野指针样程序崩溃了。
小结:对于前面的问题,不防这样来写:

include

include

void main()
{
char p=NULL,p1="hello first!";
p=new char[strlen(p1)+1];
//p=new char; //觉得最好别这样子,new char只相当于得到一个char对
char p_start=p; //象,分配一个字符的空间。
while((
(p++) = *(p1++)) != 0);

cout<
}
四 造成野指针的原因
1、指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的默认值是随机的,它会乱指一气。
2、指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。
3、指针操作超越了变量的作用范围。这种情况让人防不胜防。

五 正确使用指针
通常避免野指针的办法是正确的使用指针
1.声明一个pointer的时候注意初始化为null :
int* pInt = NULL;

2.分配完内存以后注意ASSERT:
pInt = new int[num];
ASSERT(pInt != NULL);

3.删除时候注意用对操作符:
对于new int类型的,用delete
对于new int[]类型的,用delete []

4.删除完毕以后记得给他null地址:
delete [] pInt;
pInt = NULL;

5.记住,谁分配的谁回收,不要再一个函数里面分配local pointer,送到另外一个函数去delete。

6.返回local address是非常危险的,如必须这样做,请写注释到程序里面,免得忘记。

原文

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容