首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

微软VS2015 C++核心准则分析: vtable的“无数组到指针衰减(bords.3)”?

微软VS2015 C++核心准则分析: vtable的“无数组到指针衰减(bords.3)”是指在C++中,将一个数组传递给一个函数时,数组会自动退化为指向数组第一个元素的指针。然而,对于虚函数表(vtable)指针,这种衰减是不会发生的。

vtable是C++中实现多态性的一种机制,它是一个存储了虚函数地址的表格。当一个类中包含虚函数时,编译器会为该类生成一个vtable,并将其作为该类的一个隐藏成员。每个对象都有一个指向其所属类的vtable的指针。

在C++中,当我们使用一个指向派生类对象的基类指针或引用调用虚函数时,会根据对象的实际类型来调用正确的虚函数。这是通过在vtable中查找函数地址来实现的。

而对于数组,由于其内存布局的特殊性,数组名会自动退化为指向数组第一个元素的指针。这意味着我们无法直接通过数组名来访问数组的其他元素,而只能通过指针来操作。

然而,对于vtable指针,它不会发生这种退化。因为vtable指针是一个指向vtable的指针,它需要保持指向正确的vtable,以便在调用虚函数时能够找到正确的函数地址。如果vtable指针发生了退化,就无法正确调用虚函数了。

因此,微软VS2015 C++核心准则中的“无数组到指针衰减(bords.3)”指的是在使用vtable指针时,不能将其视为数组指针进行操作,否则会导致无法正确调用虚函数的问题。

对于这个问题,可以通过避免将vtable指针与数组指针混淆来解决。在编写代码时,需要明确区分vtable指针和数组指针的使用场景,避免发生混淆。

腾讯云相关产品和产品介绍链接地址:

  • 腾讯云CVM(云服务器):https://cloud.tencent.com/product/cvm
  • 腾讯云云函数(Serverless):https://cloud.tencent.com/product/scf
  • 腾讯云数据库(云数据库):https://cloud.tencent.com/product/cdb
  • 腾讯云CDN(内容分发网络):https://cloud.tencent.com/product/cdn
  • 腾讯云人工智能(AI):https://cloud.tencent.com/product/ai
  • 腾讯云物联网(IoT):https://cloud.tencent.com/product/iot
  • 腾讯云移动开发(移动应用开发):https://cloud.tencent.com/product/mad
  • 腾讯云对象存储(COS):https://cloud.tencent.com/product/cos
  • 腾讯云区块链(BCS):https://cloud.tencent.com/product/bcs
  • 腾讯云元宇宙(Metaverse):https://cloud.tencent.com/product/mv
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

HotSpot类模型之InstanceKlass「建议收藏」

字段名 作用 _annotations Annotations类型指针,保存该类使用所有注解 _array_klasses 数组元素为该类数组Klass指针,例如ObjArrayKlass是对象数组且元素类型为...保存接口指针数组,包含_local_interfaces和间接实现接口 _default_vtable_indices 默认方法在虚函数表中索引 _fields 类字段属性,每个字段6个属性...保存接口指针数组,包含_local_interfaces和间接实现接口 _default_vtable_indices 默认方法在虚函数表中索引 _fields 类字段属性,每个字段...在创建时,会涉及C++对new运算符重载,通过重载new运算符来分配对象内存空间,然后再调用类构造函数初始化相应属性。...) 5、HotSpot源码分析C++对象内存布局 6、HotSpot源码分析之类模型 B站上有HotSpot源码分析相关视频 https://space.bilibili.com/27533329

1K30
  • C++虚函数表原理浅析

    C++虚函数表和对象存储 C++虚函数实现了多态机制,也就是用父类型指针指向其子类实例,然后通过父类指针调用实际子类成员函数,这种技术可以让父类指针有“多种形态”,这也是一种泛型技术,也就是使用不变代码来实现可变算法...(可以理解为数组里存放着指向每个虚函数指针) 即:每个类使用一个虚函数表,每个类对象用一个虚表指针 在有虚函数实例对象中,这个表被分配在了这个实例对象内存中(就和上面说一样),当我们用父类指针来操作一个子类时候...实例出对象bObj后,我们用(int*)(&bObj)强行把&bObj转成int*,取得虚函数表地址,也就是一个指向虚函数表这个数组首元素地址指针,对这个指针再次取址就可以得到第一个虚函数(数组首元素...b所指内存中虚函数表f()位置已经被Derive::f()函数地址所取代,于是在实际调用发生时,是Derive::f()被调用了,这就实现了C++动态多态 多重继承(覆盖) ?...强大C++当然是有的,细心你应该发现了,这个表(数组)其实只是变成了一个二维数组 int main() { Fun pFun = NULL; Derive dObj; int** pVtab

    1.4K32

    zergRush (CVE-2011-3874) 提权漏洞分析

    已有的分析文章:   tomken_zhang,漏洞 — zergRush,漏洞 — zergRush (补充)   Claud, Android提权代码zergRush分析 分析内容集中在zergRush.c...指针复用和vtable覆盖 能够free掉任意指针了,如何实现exploit呢?最简单办法是free掉一个带vtableC++对象指针,然后重用这个指针,从而控制vtable。...mCommands是FrameworkListener成员,它包含了若干FrameworkCommand对象指针,如果知道了FrameworkListener *this,寻址FrameworkCommand...只需要再调用dispatchCommand解析一条命令,在解析过程中,第一次strdup(tmp)返回就是这个指针,并且已经把tmp字符串复制这个地址了。...即:命令前4个字节已经成为这个FrameworkCommand对象vtable,实现了vtable任意指定。

    55920

    深入解析Java对象和类在HotSpot VM内部具体实现

    Java层面的对象会被抽象成C++一个oop类:普通对象(newFoo)是instanceOop,普通数组(new int[])是typeArrayOop,对象数组(new Bar[])是objArrayOop...对象引用位数减少允许堆中存放更多其他数据,继而提高内存利用率,但是随之而来问题是64位指针可寻址范围可能是0~242字节或0~248字节(一般64位CPU地址总线不了64位),压缩后只能寻址...但是压缩klass指针也会遇到和压缩对象指针一样问题,即寻址范围无法覆盖可能内存区域,对此,HotSpot VM解决方案也是使用基址+偏移×缩放进行定位,只是这时候32位符号整数偏移是narrowKlass...虚表是一个由函数指针构成数组,可以添加编译参数输出它[1]。...对象和类共同构成对象类二分模型,是HotSpot VM核心数据结构。

    72640

    C++与汇编小结

    C++与汇编小结 ---- 本文通过C++反编译,帮助理解C++一些概念(指针引用、this指针、虚函数、析构函数、lambda表达式), 希望能在深入理解C++其它一些高级特性(多重继承、RTTI...---- this指针 this指针中保存了所属对象首地址。 在调用成员函数过程中,编译器利用rdi寄存器保存了对象首地址, 并以寄存器传参方式传递成员函数中。...call_vfunc函数参数是基类BaseClass,再调用vfunc3函数时需要先根据虚表指针定位虚表,再通过偏移,解引用找到vfunc3代码段地址,完成调用。...,当调用这个lambda时就会执行这段指令,跟普通函数调用一致。...+反汇编与逆向分析技术揭秘》 《C++ Primer(第5版)》

    1.2K40

    C++:从技术实现角度聊聊RTTI

    C++中,由于存在多态行为,基类指针或者引用指向一个派生类,而其指向真正类型,在编译阶段是无法知道: Base *b = new Derived; Base &b1 = *b; 在上述代码中,如果想知道...info) • whole_vtable whole对象虚函数表地址 然后调用whole_type->__do_dyncast,而这也是该函数核心模块。...const void *origin; }; • whole_object 表示当前指针指向对象偏移量 • whole_type 指向 C++ 对象类型:class(基类...查看定义,__si_class_type_info 包含指向基类类型单个指针,而 __vmi_class_type_info 包含指向基类类型指针数组。...神秘面纱 多态实现-虚函数、函数指针以及变体 【Modern C++】深入理解移动语义 【Modern C++】深入理解左值、右值 智能指针-使用、避坑和实现 内存泄漏-原因、避免以及定位 GDB

    1K90

    C++】多态 ⑦ ( 多态机制实现原理 | 虚函数表概念 | 虚函数表工作机制 | vptr 指针 | 虚函数表运行时机制 | 虚函数与动态联编 )

    , 由 " 虚函数表 " 实现 ; " 虚函数表 " , 英文名称为 " Virtual Function Table " , 简称 Vtable ; C++ 编译器 通过将 虚函数指针 放入 基类..." 由 C++ 编译器 负责 创建 与 维护 , 被 virtual 关键字 修饰 虚函数 , 会自动 被 C++ 编译器 存储 " 虚函数表 " 中 ; 虚函数表 创建 : 在 类 中使用 virtual...函数指针数组 , 数组元素都是函数指针 , 具体存储都是 指向 类中虚函数 指针 ; 如果 子类 中 , 重写了 父类 virtual 虚函数 , 那么 C++ 编译器会在 子类 虚函数表...vtable ; C++ 编译器 编译 代码时 , 会自动为该类 添加 一个 vptr 指针 成员变量 , 该指针 会指向 虚函数表 ; 5、虚函数表运行时机制 " 虚函数表 " 在 C++ 编译器 编译...多个 虚函数 入口地址 ; 将 Child 对象地址 赋值给 Parent * 指针时 , 通过 Parent* 指针调用 fun 虚函数 , C++ 编译器 根本不会去关心 当前调用函数 是

    33830

    C++面试题

    C++ 基础 1. 引用和指针有什么区别? 一般指的是某块内存地址,通过这个地址,我们可以寻址这块内存;而引用是一个变量别名。指针可以为空,引用不能为空。 2....RAII技术核心是获取完资源就马上交给资源管理。标准库中智能指针和锁便是比较常用RAII工具。RAII类需要慎重考虑资源拷贝合理性。 9. 右值引用有什么作用?...C++顶层const和底层const? 顶层 const 表示指针本身是个常量; 底层 const 表示指针所指对象是一个常量。 12. 拷贝初始化、直接初始化、列表初始化?...从存储空间角度,虚函数对应一个指向vtable虚函数表指针,这大家都知道,可是这个指向vtable指针其实是存储在对象内存空间。...C++ STL 1. vector, array, deque 区别 vector是动态数组,array被封装成容器C++数组,deque是双向数组,首尾都支持增删。 2.

    1.7K42

    关于CC++ 一些自己遇到问题以及解惑

    1.数组越界造成死循环        有一位朋友在群里发了该代码,并说该代码导致了死循环??? ?        废话少说,上工具,我们来分析分析。 ?        ...这个异常是由于我们数组越界造成,而数组越界又是一种未决行为,编译器不会做任何处理,但是vs2015还是义务帮我提示了异常,所以Dev和vs该用哪一个编译器,心里有数了吧?        ...经测试,博主所使用dev和vs2015,以及一些编译器会在数组和i地址之间,用一小块内存,用来避免两者,从而一定程度上解决死循环问题,但当越界过大,还是会造成死循环.所以在使用对内存操作上,应格外小心...4.函数指针 指针函数 指针数组 数组指针 傻傻分不清 int fun();                     函数 int * fun();                   指针(样式...,元素为指针 int (*p)[];              数组(样式)指针 本质是指针 上面出现括号都是必要,不可省略,说其是一种格式也不为过,指针XX和XX指针分不清主次,可以像我一样在两者之间加上

    66841

    如何优雅地实现C++编译期多态?

    而folly::poly出来晚一些,主要使用c++新特性来实现相关功能,依赖比较少,所以本文将更多以poly实现来分析编译期多态整体实现。...指针带来问题 运行时多态一般多配合指针一起使用,这也导致基本相关代码都是配合堆内存来使用,后续又引入了智能指针缓解堆内存分配导致额外心智负担,但智能指针使用本身又带来了其他问题。...作者自己做性能分析。...get(d) 完成Data类型具体类型还原。...真正调用到实际accelerate()函数,编译期各种中间过程,基本都能被优化掉,整体性能估计跟virtual dispatch接近或者更高,有时间再结合实际工程示例测试一下相关数据,本篇性能相关分析就先到这里了

    94321

    Swift 派发机制

    缺点:缺乏动态性,无法实现继承等; 函数表派发 函数表是编译型语言常见派发方式,函数表使用数组来存储类中声明每个函数指针。对于这个表,大部分语言叫 Virtual table(虚函数表) 。...(SIL 文件中名为 sil_vtable)。...每一个类都会维护一个函数表,里面记录着类所有的函数,如果父类函数被 override,表里面只会保存被 override 之后函数。一个子类新添加函数,都会被插入这个数组最后。...扩展方法 声明作用域中方法 @objc 修饰方法或者被 objc 修饰协议中所有方法 Value Type 所有方法 其他 全局方法,staic 修饰方法;使用 final 声明类里面的所有方法...内联主要原理是:将一些函数实现直接编译入调用函数位置中去,减少函数指针栈调用,提高运行效率。

    1.1K20

    c++】多态&&虚函数&&抽象类&&继承中虚函数表详解

    重写是语法叫法,覆盖是原理层叫法 另外Func2继承下来后是虚函数,所以放进了虚表,Func3也继承下来了,但是不是虚函数,所以不会放进虚表 虚函数表本质是一个存虚函数指针指针数组,一般情况这个数组最后面放了一个...另外对象中存不是虚表,存是虚表指针 4.2 多态原理 上面分析了这个半天了那么多态原理到底是什么?...<< endl; } int main() { Base b; Derive d; // 思路:取出b、d对象头4bytes,就是虚表指针,前面我们说了虚函数表本质是一个存虚函数 // 指针指针数组...,这个数组最后面放了一个nullptr // 1.先取b地址,强转成一个int*指针 // 2.再解引用取值,就取到了b对象头4bytes值,这个值就是指向虚表指针 // 3.再强转成...VFPTR*,因为虚表就是一个存VFPTR类型(虚函数指针类型)数组

    35310

    C++知识概要

    构造函数为什么不能为虚函数 虚函数对应一个指向虚函数表指针,但是这个指向vtable 指针事实上是存储在对象内存空间。...1,因为每一个对象会有一个 vptr 指向虚函数表,具体大小根据指针大小确定 C++中要求对于类每个实例都必须有独一地址,那么编译器自动为空类分配一个字节大小,这样便保证了每个实例均有独一内存地址...包括宏定义替换、条件编译指令、头文件包含指令、特殊符号 编译 编译程序所要作得工作就是通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价中间代码表示或汇编代码 汇编 汇编过程实际上指把汇编语言代码翻译成目标机器指令过程...而 delete 会直接释放 p 指向内存,这个内存根本没有被系统记录,所以会崩溃 需要在 new [] 一个对象数组时,需要保存数组维度,C++ 做法是在分配数组空间时多分配了 4 个字节大小...,数组是 argv[],所有的参数在指针char * 指向内存中,数组中元素个数为 argc 个,第一个参数为程序名称。

    1.1K20

    微软喜提Rust拟替代CC++?凭什么!

    今日 @开源中国 一则消息引发热议:微软计划将 Rust 作为 C 和 C++ 安全替代品。 ? 根据微软安全响应中心提供数据,所有微软年度补丁中约有 70% 是针对内存安全漏洞修复程序。...xplanet,公众号:开源中国微软拥抱Rust,以作为C和C++安全替代方案 其实,自操作系统诞生以来,系统级主流编程语言,从汇编语言C++,已经发展了近50 个年头,但依然存在两个难题: 很难编写内存安全代码...只有当程序访问未定义内存时候才会产生内存错误。一般来说,发生以下几种情况就会产生内存错误: 引用空指针。 使用未初始化内存。 释放后使用,也就是使用悬垂指针。 缓冲区溢出,比如数组越界。...其中所有权系统还包括了从现代C++那里借鉴RAII 机制,这是Rust GC 但是可以安全管理内存基石。 建立了安全内存管理模型之后,再用类型系统表达出来即可。...Rust编译器会通过静态检查分析,在编译期就检查出多线程并发代码中所有的数据竞争问题。 ? 微软拥抱Rust 并非偶然,其实早先微软已在Azure IoT 网络上部分使用了Rust。

    1.3K10

    C++航海王:追寻罗杰编程之路】多态你了解多少?

    一个含有虚函数类中都至少都有一个虚函数表指针,因为虚函数 地址要被放到虚函数表中,虚函数表也简称虚表,。那么派生类中这个表放了些什么呢?我们 接着往下分析。...虚函数表本质是一个存虚函数指针指针数组,一般情况这个数组最后面放了一个nullptr。...cout << endl; } int main() { Base b; Derive d; // 思路:取出b、d对象头4bytes,就是虚表指针,前面我们说了虚函数表本质是一个存虚函数指针指针数组...,这个数组最后面放了一个nullptr // 1.先取b地址,强转成一个int*指针 // 2.再解引用取值,就取到了b对象头4bytes值,这个值就是指向虚表指针 // 3.再强转成...VFPTR*,因为虚表就是一个存VFPTR类型(虚函数指针类型)数组

    8210

    没有本机代码RCE:利用INTERNET EXPLORER中写入内容

    0x01 漏洞分析 对于上面显示代码中漏洞来说,根源在于IDispatchEx允许使用属性两种不同put操作。属性典型put操作是将标量值分配给属性,例如,整数或字符串。...第一个字段是主vtable指针,这里以红色显示。我们将用指向伪造vtable指针来替换它,其中一个函数指针已被指向WinExec指针所替换。第二个字段,以蓝色显示,是一个引用计数器。...我们第一个挑战是:在第一个字段中,我们怎样才能编写一个4字节值,使其既是vtable指针,同时还是ANSI命令字符串前4个字符?...我解决方案是将下列内容写入对象前8个字节: 这下读者应该能看明白了吧?前4个字节可以作为指针值0x28282828读取,我们可以将伪造vtable放在该位置。...在Windows 10上,代码执行前有一条最后防线:CFG。CFG会阻止尝试从vtable调用WinExec吗?它并没有这么做。微软似乎认为使用CFG来限制对WinExec调用是不恰当

    1.3K20

    多态与虚(函数)表

    虚函数表本质是一个存虚函数指针指针数组,一般情况这个数组最后面放了一个nullptr。 5....总结一下派生类虚表生成:a.先将基类中虚表内容拷贝一份派生类虚表中 b.如果派生类重写了基类中某个虚函数,用派生类自己虚函数覆盖虚表中基类虚函数 c.派生类自己新增加虚函数按其在派生类中声明次序增加到派生类虚表最后...3.2️⃣多态原理 上面分析了这个半天了那么多态原理到底是什么?...指针指针数组,这个数组最后面放了一个nullptr // 1.先取b地址,强转成一个int*指针 // 2.再解引用取值,就取到了b对象头4bytes值,这个值就是指向虚表指针 // 3.再强转成...VFPTR*,因为虚表就是一个存VFPTR类型(虚函数指针类型)数组

    57120

    【leetcode刷题】分发饼干【455】+数组拆分 I【561】

    【leetcode刷题】分发饼干【455】 一、题目-- 455.分发饼干 1.题目描述 二、解题报告 1.思路分析 2.代码详解 3.注意事项C++ 三、题目 -- 561....数组拆分 I 1.题目描述 2.代码详解 一、题目-- 455.分发饼干 1.题目描述 二、解题报告 1.思路分析 贪心算法 人和饼干都从小到大排序,进行匹配尽量让小饼干给胃口小的人吃【人也贪心,...+ sort用法 在C++中使用sort()函数需要使用#include sort(begin, end, cmp) begin为指向待sort()数组第一个元素指针...end为指向待sort()数组最后一个元素下一个位置指针 cmp参数为排序准则,cmp如果不写的话,默认从小到大进行排序【从大小排序可以将cmp参数写为greater()就是对int数组进行排序...数组拆分 I 1.题目描述 上面那道会做了以后,这道简简单单搞定定~~~~~讲解 2.代码详解 class Solution { public: int arrayPairSum(vector

    37010
    领券