野指针及c++指针使用注意点
避免野指针的产生
“野指针”的成因主要有:
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; //释放时报错
}
结果:卡死

YHAB`$4XUW7T(VAK37.png)
改进:
#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申请的内存空间中;
野指针及c++指针使用注意点的更多相关文章
- NULL指针、零指针、野指针
1.1.空指针 如果 p 是一个指针变量,则 p = 0; p = 0L; p = '\0'; p = 3 - 3; p = 0 * 17;p=(void*)0; 中的任何一种赋值操作之后, p 都成 ...
- 野指针、NULL指针和void*
一.野指针 “野指针”不是NULL指针,是指向“垃圾”内存的指针. “野指针”的成因主要有三种: (1)指针变量没有被初始化.任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱 ...
- 关于空指针NULL、野指针、通用指针 (转)
reference:https://www.cnblogs.com/losesea/archive/2012/11/16/2772590.html 首先说一下什么是指针,只要明白了指针的含义,你就明白 ...
- 关于空指针NULL、野指针、通用指针
http://www.cnblogs.com/losesea/archive/2012/11/16/2772590.html 首先说一下什么是指针,只要明白了指针的含义,你就明白null的含义了.假设 ...
- 空指针、NULL指针、零指针
1. 空指针.NULL指针.零指针 1.1 什么是空指针常量 0.0L.'\0'.3 - 3.0 * 17 (它们都是“integer constant expression”)以及 (void*)0 ...
- void指针和NULL指针
Void指针和NULL指针 Void指针: Void指针我们称之为通用指针,就是可以指向任意类型的数据.也就是说,任何类型的指针都可以赋值给Void指针. 举例: #include<stdio. ...
- C语言指针专题——使用指针要注意这些
本文为原创,欢迎转发: 欢迎关注微博与微信号:C语言编程技术分享 C语言中,指针的概念有点难懂,使用起来稍微不注意,也会遇到各种问题.在本文中,我列举出了几个使用指针不当的方式,希望朋友们在编程实践中 ...
- 第37课 智能指针分析(指针特征操作符( -> 、 *)重载)
1. 永恒的话题:内存泄漏 (1)动态申请堆空间,用完后不归还 (2)C++语言中没有垃圾回收的机制 (3)指针无法控制所指堆空间的生命周期------------指针是变量,可以指向内存堆空间,但是 ...
- C与指针(结构体指针,函数指针,数组指针,指针数组)定义与使用
类型 普通指针 指针数组(非指针类型) 数组指针 结构体指针 函数指针 二重指针 定义方式 int *p; int *p[5]; int (*p)[5]; int a[3][5]; struct{.. ...
随机推荐
- vc如何编译链接opengl库
强烈推荐的一篇强大的OpenGl学习博文OpenGL入门学习 vc2012如何链接opengl库? 首先,我们需要下载opengl的库文件,http://pan.baidu.com/s/1kTsjkZ ...
- Matlab之文件读写
读文件: (0)自己添加 你可以将txt的一些文本数据直接拷贝到matlab窗口,然后保存为mat文件,下次就可以直接采用load函数了. (1)Load load 从Matlab的数据文件.mat ...
- 【CSS3】---text-overflow 与 word-wrap
text-overflow用来设置是否使用一个省略标记(...)标示对象内文本的溢出. 语法: 但是text-overflow只是用来说明文字溢出时用什么方式显示,要实现溢出时产生省略号的效果,还须定 ...
- DWZ (JUI) 教程 table 排序
dwz排序是后台排序,不是前台的js排序,他的流程和搜索,分页是一样的,当你点击排序的按钮时,从新发送请求刷新当前的navTable 和 dialog. <th width="60&q ...
- DWZ (JUI) 教程 国际化问题(多语言/语言切换)
DWZ 国际化也是比较简单的,网站的内容国际化和常规的项目国际化是一样的,不要做出特殊的调整. DWZ 自身框架的国际化,比如 翻页的上一页下一页等信息.这些信息都是在dwz.frag.xml 文件当 ...
- SQL备份(全)
====================================================================== SQL备份 ======================= ...
- 调用支付宝PHP接口API实现在线即时支付功能(UTF-8编码)
这次在项目中要实现订单功能,所以要完成在线支付,在线支付一般有网银支付和第三方支付(支付宝.paypal等)这两种途径,未简单起见,先完成支付宝在线支付功能,由于项目基于Yii框架,且使用UTF-8编 ...
- Debian下配置SSH服务器的方法
Debian 503版本中实现的,Debian默认好像是没有ssh支持的. SSH的安装apt-get install openssh-serverapt-get install sshSSH的配置O ...
- UI2_UINavigationBar
// // AppDelegate.m // UI2_UINavigationBar // // Created by zhangxueming on 15/7/6. // Copyright (c) ...
- eclipse中tomcat配置(待完善)
tomcat版本:apache-tomcat-6.0.29 项目结构: 一.新建server方式 二.eclipse tomcat plugin方式 tomcat plugin方式必须保证 ...