当前位置: 首页 > news >正文

荆州网站建设流程网站开发 行业动态

荆州网站建设流程,网站开发 行业动态,网站后台系统功能,html怎么做网站设计空指针解引用引起程序奔溃是c/c中最常见的稳定性错误之一。 显然并非所有使用空指针的语句都会导致奔溃,那什么情况下使用空指针才会引起程序奔溃呢?有一个判断标准:判断空指针是否会导致访问非法内存的情况,如果会导致访问非法内…

空指针解引用引起程序奔溃是c/c++中最常见的稳定性错误之一。
显然并非所有使用空指针的语句都会导致奔溃,那什么情况下使用空指针才会引起程序奔溃呢?有一个判断标准:判断空指针是否会导致访问非法内存的情况,如果会导致访问非法内存就会奔溃,否则不会奔溃

常见的空指针操作

考虑下面的代码,用到空指针test的6条语句(#1#6)中哪些会引起程序奔溃?

struct Test {void method_01() {  }virtual void method_02() {  };int value;static void StFunction() {  }static int stValue;
};
int Test::stValue = 1;int main() {Test* test = nullptr;Test copy = *test;           // #1int value = test->value;     // #2    int stVAlue = test->stValue; // #3test->StFunction();          // #4test->method_01();           // #5test->method_02();           // #6
}

答案如下

序号代码含义是否会引起程序奔溃
#1对指针取值
#2通过指针访问成员变量
#3通过指针访问静态变量
#4通过指针调用静态函数
#5通过指针调用成员函数
#6通过指针调用虚函数

面对这个答案大家可能会有疑问:

  • 为什么空指针test访问成员变量会奔溃而访问静态变量不会奔溃?
  • 为什么空指针test调用静态函数和非虚成员函数不会奔溃而调用虚函数会奔溃?

原因隐藏在“对空指针解引用会引发程序奔溃”这句话的关键词解引用里。怎么理解引用呢?可以简单理解为访问与指针有关的内存地址。

从程序运行的角度来看,问题的本质是访问非法内存会引起程序奔溃。所以空指针是否会引起程序奔溃的一个判断标准总结为:判断空指针是否会导致访问非法内存的情况,如果会导致访问非法内存就会奔溃,否则不会奔溃

接下来我们逐个分析#1#6这些语句的内存访问情况,会涉及到一些c++底层知识,也是本文的主要内容。

深入理解

在详细分析之前先看看Test类的内存结构
在这里插入图片描述

注意:虚函数表和虚函数表指针不是必须的,只有定义或者继承了虚函数的类型才会分配这两块内存。

内存分为两部分(可以结合进程的内存结构和ELF文件结构来理解):
静态内存:编译阶段确定地址的内存,与实例无关且全局只存在一份。如静态变量、虚函数表、代码段。
动态内存:运行阶段才能确定地址的内存,与实例绑定。如成员变量、虚函数表指针(虚表指针实际上也是成员变量,特殊在它是由编译器添加的)。

所以用到空指针test的6条语句本身访问内存情况如下

编号操作访问符号符号类型符号地址备注
Test* test = nullptr;----
#1Test copy = *test;test指针类型局部变量--
#2int value = test->value;Test::value成员变量0x8value相对Test首地址的偏移量为8字节,因此地址为 0x0 + 8 = 0x8
#3int stVAlue = test->stValue;Test::stValue静态变量固定地址编译阶段分配好的地址,与指针test无关
#4test->StFunction();Test::StFunction静态函数固定地址编译阶段分配好的地址,与指针test无关
#5test->method_01();Test::method_01非虚成员函数固定地址编译阶段分配好的地址,与指针test无关
#6test->method_02();虚函数表指针指针类型成员变量0x0虚函数表指针 相对Test首地址的偏移量为0字节,因此地址为 0x0 + 0 = 0x0
Test::method_02虚函数固定地址编译阶段分配好的地址,与指针test无关

了解Test的内存结构之后,分析空指针test的6条语句是否会引起程序奔溃就变得清晰很多:

#1取值操作:Test copy = *test;

空指针test指向的地址是0x0,取值操作*test访问的是非法内存地址0x0,所以会引起程序奔溃。

#2访问成员变量:int value = test->value;

test->value是在访问非法地址0x8,所以会引起程序奔溃。

#3访问静态变量:int stVAlue = test->stValue;

访问静态变量和静态函数的方式有2种
通过实例访问:例如 int stVAlue = test->stValue;test->StFunction();
通过类名访问:例如 int stVAlue = Test::stValue;Test::StFunction();
两种访问方式的效果是一样的,实际上通过类名访问的方式更常见。本文使用通过实例访问的方式做示例是为了与其他操作做对比。

将示例代码访中问静态变量和静态函数的语句替换成通过类名访问的方式后,会发现访问静态变量和调用静态函数的语句与test指针本身没有半毛钱关系。

test->stValue等价于Test::stValue,这条语句访问的是stValue的地址而这个地址必然是有效的,与空指针test没有任何关系,所以不会引起程序奔溃。

#5调用非虚成员函数:test->method_01();

成员函数的本质
从内存结构上看成员函数和静态函数似乎没有区别,实际上他俩确实没有区别。可以这样理解:c++是比c语言多了很多特性的增强版,成员函数就是其中一个特性,这个特性类似于语法糖,目的是为了简化调用成员函数(一种特殊的函数)的语法。

成员函数特殊在第一个形参一定是this指针(隐式形参,不需要明确定义,编译器会在编译阶段补全),所以我们可以把成员函数退化成等价的c风格全局函数,例如
定义退化:成员函数void Test::method_01()可以退化成全局函数void method_01(Test* self)
调用退化:调用成员函数test->method()可以退化成调用全局函数method_01(test)

同样,test->method_01相当于method_01(test),是在访问method_01的地址而这个地址必然是有效的,虽然入参test是空指针,但调用函数这条语句本身不会访问这个空指针的内存,因此不会引起程序奔溃。

注意:调用非虚成员函数这条语句本身不会引起奔溃,但由于通常情况下成员函数的实现都会访问成员变量,所以程序可能会在成员函数内部因为解引用空指针this(也就是入参test)而奔溃。最常见具有迷惑性的奔溃现场比如
● 构造函数的内部空指针错误 —— 在访问成员变量或者虚函数的语句奔溃;
● 非虚析构函数内部空指针错误 —— 在访问成员变量或者虚函数的语句奔溃;
构造函数和非虚析构函数是特殊的非虚成员函数,在分析奔溃问题的时候可以把他们当作普通的非虚成员函数一样对待。

#6调用虚函数:test->method_02();

虚函数调用过程
虚函数是c++多态的核心技术(不知道多态是什么的同学出门右转找个角落自己学习一下),保证在继承结构中能正确调用子类的实现。虚函数表、虚函数表指针就是用来完成虚函数调用的,调用虚函数主要有下面几个步骤:
● 通过虚函数指针访问对应的虚函数表;例如Test的实例的虚函数指针指向Test的虚函数表;
● 在虚函数表中找到需要调用的函数;
● 调用这个函数;

调用虚函数的情况与调用非虚函数有所不同,test->method_02()不会直接访问函数method_02()的地址,而是首先通过虚函数表指针访问虚函数表,在通过空指针test访问虚函数指针时会访问非法地址0x0,因此会引起程序奔溃。

http://www.yayakq.cn/news/558031/

相关文章:

  • 制作微信网站免费发布推广的网站
  • 网络营销网站建设实训wordpress会员可见插件
  • 网站建设费入何科目网架加工厂选择徐州先禾网架
  • 怎样在内网建设一个网站wordpress数据库重装
  • 网络公司+网站建设+小程序wordpress接收不到邮件
  • 怎么做网站弹窗通知手机免费网站制作
  • 深圳建站公司兴田德润放心企业网站的作用有哪些
  • 关于动物自己做的网站wordpress文档模板
  • 建设一个网站要花多少时间十大没必要装修
  • 网站 入站规则 设置广州网站建设制作的公司
  • 专门做进口产品的网站6创建一个购物网站
  • 农村电商网站建设计划书怎样在wordpress里添加菜单
  • 四川 网站建设深圳代理记账公司电话
  • 2015做哪些网站致富广西人事考试网
  • 做网站的公司重庆外贸基本流程
  • 查询公司水利平台网站学会网站建设的重要性
  • 知识付费网站制作深圳网站建设的基本知识
  • 瑞安 网站建设文件管理系统
  • 北京企业建站哪家好WordPress 发表文章api
  • 做承诺的网站百度推广退款电话
  • 好文案网站苏州工业园区发布
  • 潍坊网站制作招聘咸阳软件开发
  • 一般网站开发公司东莞搜索seo网站关键词优化
  • 东莞企业建站程序投诉举报网站建设方案
  • 大连网站推广招聘软件界面设计工具下载
  • 网站管理助手数据库和wordpress价值
  • 网站友情链接怎么添加自助建站平台源码
  • 网站没备案能访问吗手机端自定义做链接网站
  • 溧阳网站建设制作呼伦贝尔北京网站建设
  • 济南精品建站外包公司价格网站建设和