避免野指针的产生

“野指针”的成因主要有:

1)指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。

char *p; //此时p为野指针

2)指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针.

char *p=new char[];  //指向堆中分配的内存首地址,p存储在栈区
cin>> p;
delete []p; //p重新变为野指针

3)指针操作超越了变量的作用范围。

char *p=new char[]; //指向堆中分配的内存首地址
cin>> p;
cout<<*(p+); //可能输出未知数据

指针的注意点:

a.指针指向常量存储区对象

char *p="abc";

此时p指向的是一个字符串常量,不能对*p的内容进行写操作,如srtcpy(p,s)是错误的,因为p的内容为“abc”字符串常量,该数据存储在常量存储区,但可以对指针p进行操作,让其指向其他的内存空间。

b.资源泄漏

问题:

 #include<iostream>
using namespace std;
void main()
{
char *p=new char[]; //分配三个字符空间,p指向该内存空间
p="ab"; //此时p指向常量“ab”,而不再是new char分配的内存空间了,从而造成了资源泄漏
delete []p; //释放时报错
}

结果:卡死

改进:

 #include<iostream>
using namespace std;
void main()
{
char *p=new char[]; //分配三个字符空间,p指向该内存空间
strcpy(p,"ab"); //将"ab"存储到p指向的内存空间
delete []p; //ok
}

结果:正确

c.内存越界

 char *p=new char[];  //分配三个字符空间,p指向该内存空间
strcpy(p,"abcd"); //将abcd存处在分配的内存空间中,由于strlen("abcd")=4>3,越界
delete []p; //ok

d.返回值是指针

问题:数组p[]中的内容为“hello world”,存储在栈区,函数结束时内容被清除,p变为野指针,可能导致乱码

 #include<iostream>
using namespace std;
char *f()
{
char p[]="abc";
return p;
}
void main()
{
cout<<f()<<endl;
}

结果:

 改进:

1.加static限定,延长数组生存期

 #include<iostream>
using namespace std;
char *f()
{
static char p[]="abc"; //此时数组为静态数组,存储在全局/静态区,生存期到程序结束,因此函数结束时不会销毁p
return p;
}
void main()
{
cout<<f()<<endl;
}

结果:

2.定义成指针型数组

 #include<iostream>
using namespace std;
char *f()
{
char *p="abc"; //"abc"存储在文字常量区,p是指向常量的指针,生存期到程序结束
return p;
}
void main()
{
cout<<f()<<endl;
}

结果:

3.动态分配存储空间,存储在堆区

 #include<iostream>
using namespace std;
char *f()
{
char *p=new char[]; //动态分配存储空间,p指向堆区
strcpy(p,"abc"); // 这里不能用p="abc",前面已经说明
return p;
}
void main()
{
cout<<f()<<endl;
}

结果:

 e.指针做形参

即所谓的地址传递,我们都知道地址传递的方式,形参的改变会导致实参的改变,但要注意的是,这里的改变是指指针所指内容的改变,而不是指针值的改变。因此,当形参改变会导致实参改变时,指针所指的内容是非const类型的,否则会出错。

1.改变指针内容:

 void swap(int *a,int *b)   //交换的是*a,*b,即指针的内容,而不是指针a,b
{
int t;
t=*a;
*a=*b;
*b=t;
}

2.改变指针值:

 #include<iostream>
using namespace std;
void fun(char *p)
{
p="cba"; //“cba”存放在文字常量区,让p指向常量"abc",这里改变的是指针值,实参并不会改变
}
void main()
{
char *p="abc"; //“abc”存放在文字常量区,p指向常量"abc"
fun(p);
cout<<p<<endl; //输出"abc",而不是"bca"
}

结果:

继续看下面的情况,修改指针的内容:

 #include<iostream>
using namespace std;
void fun(char *p)
{
p[]='c'; //改变p的内容,即修改p[0]
}
void main()
{
char *p="abc"; //p指向常量"abc"
fun(p);
cout<<p<<endl; //error,p所指内容为常量,不能修改
}

结果:

注:p="ab"和strcpy(p,"ab"),含义不一样,前者指针p指向常量“ab”存储区域的首地址,改变了p最开始指向的new申请的内存空间;而后者是将“ab”分配到new申请的内存空间中;

最新文章

  1. linux eclipse3.6.1 maven安装
  2. oracle中DDL DML指什么?
  3. c# 调用 CRFs应用程序
  4. Tao 1.2.0图形框架发布
  5. 代码,显示IPhone剩余磁盘空间
  6. 为什么在Python3.4.1里输入print 10000L或10000L失败
  7. Webstrom 常用操作记录
  8. [noip2016]洛谷2827
  9. mysql mycat 中间件安装与使用
  10. js jquery 遍历 for,while,each,map,grep
  11. oracle  的sqlplus 工具进行翻译的rlwrap 安装教程
  12. shell之ulimit应该注意的事项
  13. 十四、ChainOfResponsibility 责任链模式
  14. 读书笔记《Spring Boot实战 —— Java EE 开发的颠覆者》
  15. NiXi.DAY06东软实训.:面向对象思想~抽象~static~final~构造方法及其重载
  16. HDU 4825 Xor Sum (裸字典树+二进制异或)
  17. [javase学习笔记]-6.3 对象的内存体现
  18. 车架号识别,VIN码识别 助力汽车后市场
  19. PAT L1-044 稳赢
  20. 动画切换效果之push、pop、present、dismiss

热门文章

  1. hdu 4081 最小生成树+树形dp
  2. HTTP协议状态码的含义
  3. poj 3979 分数加减法
  4. Abp Zero——前端如何新增功能模块
  5. Asp.Net-创建网站的快捷方式到桌面,开始菜单,收藏夹
  6. 一个页面多Table多分页的问题
  7. sicily 1022. Train Problem
  8. C++模板实例化(1)
  9. ABAP OO与ALV结合方式探索(2)
  10. 【风马一族_代码英语】代码英语之八 ADB