一段C++代码想到的问题
今天在学习《Unix环境高级编程》,第七章进程环境给出了一个进程的内存分布示意图,从下往上依次为“正文段->初始化数据->未初始化数据(默认初始化为0)->堆(从低地址到高地址)->栈(从高地址到低地址)->命令行参数和环境变量”。其中的正文段也叫代码段,是可共享的,只读的。
这个时候我就想到上次做的腾讯的一个题目,其实很简单,大概意思如下所示代码所示。大概意思是,先创建了一个类的对象a,再将a内存清0,然后直接调用两个的一个是虚函数一个是非虚函数,看看能否正确访问。另一个是创建了一个类的对象指针,然后将该内存区域清0,通过指针调用类的这两个函数。
结果如代码中所示。当时还无法理解为什么是这样,今天看了这个就试着分析下。首先A中的函数,无论是虚函数还是非虚函数都在编译器被放在进程的代码段,等待被调用。通过直接调用,会直接在代码段找相应的函数调用即可,因此第一种情况下都是正确运行的。而通过指针调用,如果是非虚函数则会直接在代码段调用相应的函数,而如果是虚函数,则会通过指向对象的内存中的虚函数指针找到虚函数表,调用相应的在代码段的虚函数。清零的情况下,虚函数指针已经不复存在了,因此会出现访问虚函数出错。
#include<iostream>
#include<string>
using namespace std;
class A {
public:
int a;
virtual int vfun() { cout << "virtual"; return 0; }
void notvfun() { cout << "not virtual"; }
};
class B { };
int main() {
A a;
memset(&a, 0, sizeof(A));
a.notvfun();//right
a.vfun(); //right A *pa=new(A);
memset(pa, 0, sizeof(A));
pa->notvfun();//right
pa->vfun();//wrong }
一段C++代码想到的问题的更多相关文章
- 数据段、代码段、堆栈段、BSS段的区别
进程(执行的程序)会占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用 途 不一而不尽相同,有些内存是事先静态分配和统一回收的 ...
- C# 一段绘图代码 在form_load事件不能显示图
今天无意将一段绘图代码 写在form_load事件了,结果不能显示绘图.(代码:Graphics g = this.CreateGraphics();Pen pen = new Pen(Color.R ...
- 【转】可执行程序包括BSS段、数据段、代码段
可执行程序包括BSS段.数据段.代码段(也称文本段). 一.BSS BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域.特点是:可 ...
- 五个数据段之代码段、数据段、BSS、栈、堆
继上文讲完了对内存管理的一些知识,下面笔者再对上篇文章的内容加以拓展,那么我们今天就来说一说5个数据段 五个数据段 进程(执行的程序)会占用一定数量的内存,它或是用来存放磁盘载入的程序代码,或是存放取 ...
- 让多个HTML页面 使用 同一段HTML代码
需求背景 一个网站有多个网页:一个网页,可以分为很多部分,举个例子,下面是一个特别简单的网页结构: 一般情况下,footer都是用于标识网站的相关信息(备案.联系方式.制作方),每一个页面都是相 ...
- C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)
BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段 : ...
- c#代码 天气接口 一分钟搞懂你的博客为什么没人看 看完python这段爬虫代码,java流泪了c#沉默了 图片二进制转换与存入数据库相关 C#7.0--引用返回值和引用局部变量 JS直接调用C#后台方法(ajax调用) Linq To Json SqlServer 递归查询
天气预报的程序.程序并不难. 看到这个需求第一个想法就是只要找到合适天气预报接口一切都是小意思,说干就干,立马跟学生沟通价格. 不过谈报价的过程中,差点没让我一口老血喷键盘上,话说我们程序猿的人 ...
- java如何从一段html代码中获取图片的src路径
java如何从一段html代码中获取图片的src路径 package com.cellstrain.icell.Test; import java.util.ArrayList;import java ...
- bss段,代码段及数据段,堆栈段的区别
bss段,代码段及数据段,堆栈段的区别 时间:2012-11-21 10:0772人阅读 BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英 ...
随机推荐
- JavaScript---网络编程(6)-Dom和Bom模型概念讲解(节点获取,window对象)
本节讲Dom和Bom模型概念讲解(节点获取,window对象). out.js: 写了2个输出到页面的函数. function println(param){ document.write(param ...
- [comparator] 策略模式
我们知道策略模式,首先是各种策略可以替换,其实我们常见的Arrays.sort();中可以指定比较器,实现comparator接口的比较器,作为对象传入,这不就是策略模式吗,好理解吧
- linux关于bashrc与profile的区别(转)
转载自:http://www.cnblogs.com/hongzg1982/articles/2101792.html bashrc与profile的区别 要搞清bashrc与profile的区别,首 ...
- javascript日志框架使用
1.在页面中引入js文件 官网:http://log4javascript.org/index.html ```javascript <script src="http://cdn.b ...
- engine中调整Element的上下显示顺序(遮盖)
pGraphicsContainer.AddElement(pElement, 0); Engine中IGraphicsContainer类似于栈,加Element时,默认加到第一个,所以会将之前加的 ...
- tar打包和解压命令
如果你有一个大文件 想下载下来 但是又太大 可以压缩一下 然后打包 #压缩 tar -czvf ***.tar.gz tar -cjvf ***.tar.bz2 #解压缩 tar -xzvf ***. ...
- mongodb基本操作及存储图片显示方案
先介绍下mongodb的基本操作及使用 第一部:开启安全性验证 如果需要给MongoDB数据库使用安全验证,则需要用--auth开启安全性检查,则只有数据库认证的用户才能执行读写操作,开户安全性检查, ...
- MISCONF Redis is configured to save RDB snapshots
今天客户突然反馈用我们的api出现了下面的这个错误 MISCONF Redis is configured to save RDB snapshots, but is currently not ab ...
- 半斤八两(创业兴家版 打工仔心声'98 Remix)
创业兴家打工仔 刻苦工作热诚日夜维系天天专心向上依足正轨 结力好比兄弟努力一生打工仔 相亲相爱朋情日夜传递彼此一家那用分高与低 要互相多鼓励 半斤八两 莫记往昔的创伤半斤八两 面对春光应插秧半斤八两 ...
- Least Common Multiple
地址:http://www.codewars.com/kata/5259acb16021e9d8a60010af/train/python 题目: Write a function that calc ...