野指针的三种类型及常见问题注意点

6 篇文章 0 订阅

野指针的三种类型

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

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

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

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

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

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

常见问题

1)指针指向常量存储区

char *p="abc";

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

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

此时运行会直接卡死
改进方案:

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

3)内存越界

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

4)返回值是指针

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

数组p[]中的内容为“hello world”,存储在栈区,函数结束时内容被清除,p变为野指针,可能导致乱码
改进方案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[5];  //动态分配存储空间,p指向堆区
     strcpy(p,"abc");   // 这里不能用p="abc",前面已经说明
     return p;
 }
 void main()
 {
    cout<<f()<<endl;
 }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值