今天在学习《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++代码想到的问题的更多相关文章

  1. 数据段、代码段、堆栈段、BSS段的区别

    进程(执行的程序)会占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用 途 不一而不尽相同,有些内存是事先静态分配和统一回收的 ...

  2. C# 一段绘图代码 在form_load事件不能显示图

    今天无意将一段绘图代码 写在form_load事件了,结果不能显示绘图.(代码:Graphics g = this.CreateGraphics();Pen pen = new Pen(Color.R ...

  3. 【转】可执行程序包括BSS段、数据段、代码段

    可执行程序包括BSS段.数据段.代码段(也称文本段). 一.BSS BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域.特点是:可 ...

  4. 五个数据段之代码段、数据段、BSS、栈、堆

    继上文讲完了对内存管理的一些知识,下面笔者再对上篇文章的内容加以拓展,那么我们今天就来说一说5个数据段 五个数据段 进程(执行的程序)会占用一定数量的内存,它或是用来存放磁盘载入的程序代码,或是存放取 ...

  5. 让多个HTML页面 使用 同一段HTML代码

    需求背景 一个网站有多个网页:一个网页,可以分为很多部分,举个例子,下面是一个特别简单的网页结构:    一般情况下,footer都是用于标识网站的相关信息(备案.联系方式.制作方),每一个页面都是相 ...

  6. C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)

      BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段 : ...

  7. c#代码 天气接口 一分钟搞懂你的博客为什么没人看 看完python这段爬虫代码,java流泪了c#沉默了 图片二进制转换与存入数据库相关 C#7.0--引用返回值和引用局部变量 JS直接调用C#后台方法(ajax调用) Linq To Json SqlServer 递归查询

    天气预报的程序.程序并不难. 看到这个需求第一个想法就是只要找到合适天气预报接口一切都是小意思,说干就干,立马跟学生沟通价格. ​ ​不过谈报价的过程中,差点没让我一口老血喷键盘上,话说我们程序猿的人 ...

  8. java如何从一段html代码中获取图片的src路径

    java如何从一段html代码中获取图片的src路径 package com.cellstrain.icell.Test; import java.util.ArrayList;import java ...

  9. bss段,代码段及数据段,堆栈段的区别

    bss段,代码段及数据段,堆栈段的区别 时间:2012-11-21 10:0772人阅读 BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英 ...

随机推荐

  1. ARM学习笔记6——程序状态寄存器访问指令

    这两条指令结合,可用于对CPSR或SPSR进行读/写操作. 当需要保存或修改当前模式下CPSR或SPSR的内容时,首先必须将这些内容传递到通用寄存器中 1.MRS指令(Move to Register ...

  2. Cogs 309. [USACO 3.2] 香甜的黄油 dijkstra,堆,最短路,floyd

    题目:http://cojs.tk/cogs/problem/problem.php?pid=309 309. [USACO 3.2] 香甜的黄油 ★★   输入文件:butter.in   输出文件 ...

  3. Bzoj 2456: mode 数论,众数

    2456: mode Time Limit: 1 Sec  Memory Limit: 1 MBSubmit: 2843  Solved: 1202[Submit][Status][Discuss] ...

  4. WPP

    WPP(Wavefront Parallel Processing) 上一行的第二个LCU处理完毕,即对当前行的第一个LCU的熵编码(CABAC)概率状态参数进行初始化,如图5所示.因此,只需要上一行 ...

  5. 使用二维NDRange workgroup

    作为初学者一直,经过多次的上网搜索你一定会看到迈克老狼的向量加法的示例,不知道你是否和我一样,刚开始并不是很准确的知道他的add.cl写的代码的意思,源码如下: #pragma OPENCL EXTE ...

  6. kvm 性能调优

    CPU Tuning Cache share tuning 对于物理 CPU,同一个 core 的 threads 共享 L2 Cache,同一个 socket 的 cores 共享 L3 cache ...

  7. windows ntp安装及调试

    Setting up NTP on Windows It's very helpful that Meinberg have provided an installer for the highly- ...

  8. poj 2186 Popular Cows【tarjan求scc个数&&缩点】【求一个图中可以到达其余所有任意点的点的个数】

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27698   Accepted: 11148 De ...

  9. 普通Windows控制台窗口运行nmake编译VC

    我的GDAL编译都是在VS2012提供的prompt windows里面运行nmake完成的.但是如果想将编译自动化,放到Jenkins里面怎么办呢?首先没有VS2012的工程,也不想费力去生成一个, ...

  10. C程序设计语言--宏定义

    C语言中的宏定义 C语言中的宏定义也叫做预处理命令,预处理命令是C语言本身的组成部分,不能直接对它们进行编译. 1.基本概念: 1>预处理不是C语句,是在编译前进行的 2>预处理功能主要用 ...