探讨C++ 变量生命周期、栈分配方式、类内存布局、Debug和Release程序的区别
探讨C++ 变量生命周期、栈分配方式、类内存布局、Debug和Release程序的区别(一)
今天看博客园的文章,发现博问栏目中有一个网友的问题挺有趣的,就点进去看了下,标题是“C++生存期问题”,给出链接:http://q.cnblogs.com/q/51133/
本文会以此问题作为讨论的实例,来具体讨论以下四个问题:
(1) C++变量生命周期
(2) C++变量在栈中分配方式
(3) C++类的内存布局
(4) Debug和Release程序的区别
也许您觉得这些讨论问题没有实际意义,应该多做些提高生产力的事情,如同重复发明轮子也是没有意义的。
笔者同意这个观点,但是,作为一个有追求的程序员,应该知其然而且知其所以然,更应该知道轮子是怎么造出来的,不是吗?
当然,限于篇幅,本文可能只是抛砖引玉,更多的知识,一定是大家自己去探索的。
不多说,进入正题。
实验环境:Win7 32bit系统 + VS2008 SP1
问题现象:
先阅读以下程序:

#include "stdafx.h"
#include<iostream>
#include<windows.h>
using namespace std;
class T
{
protected:
int t;
public:
T(int r=0):t(r){}
void showNum(){cout<<t<<endl;}
}; class T1:public T
{
private:
int x;
public:
T1(int r):x(r),T(r){}
void show(){cout<<"x="<<x<<endl;}
}; class T2:public T
{
private:
int x;
public:
T2(int r):x(r*r),T(r){}
void show(){cout<<"x="<<x<<endl;}
}; void main()
{
T* p[10];
for(int i=0;i<5;i++)
{
if(i%2==0)
{
T1 r(2);
p[i]=&r;
cout<<&r<<endl;
}
else
{
T2 r(3);
p[i]=&r;
cout<<&r<<endl;
}
}
for(int i=5;i<10;i++)
{
if(i%2==0)
{
T1 r(4);
p[i]=&r;
cout<<&r<<endl;
}
else
{
T2 r(5);
p[i]=&r;
cout<<&r<<endl;
}
}
for(int i=0;i<10;i++)
{
p[i]->showNum();
}
system("pause");
}

不急着往下看,先预测此程序输出。
一般来说,我们预测的输出会是什么结果呢?
首先Debug版本和Release版本应该输出结果是相同的,或者规律是相同的。
当0 <= i < 5时,输出5个地址,应该是不同的,逐个递增,生成的局部变量存放在栈中;
当5 <= i < 10时,又输出5个地址,应该也是不同的,也是逐个递增,生成的局部变量存放在栈中;
最后循环调用p[i]->showNum()这个方法10次,输出的结果应该是不可知的,因为P[i]指向的对象都已经失效。
我们来看看实际输出的结果:
Debug版本:
当0 <= i < 5时,输出5个地址,是一种交替状输出,分别是001FF750和001FF740。
当5 <= i < 10时,又输出5个地址,也是交替状输出,分别是001FF714和001FF724。
最后循环调用p[i]->showNum()这个方法10次,输出的结果是正确的,似乎那些栈中的局部对象未失效。
Release版本:
当0 <= i < 5时,输出5个地址,是一种交替状输出,分别是001CFB00和001CFB08。
当5 <= i < 10时,又输出5个地址,也是交替状输出,奇怪的是地址的值也是001CFB00和001CFB08。
最后循环调用p[i]->showNum()这个方法10次,输出的结果全是5和4,似乎前5次输出失效了,后5次没有失效。
为什么?
大家可以先思考,有想法可以留言指出。限于篇幅,笔者的下一篇博客将给出具体的分析。
探讨C++ 变量生命周期、栈分配方式、类内存布局、Debug和Release程序的区别的更多相关文章
- java 静态变量生命周期(类生命周期)
Static: 加载:java虚拟机在加载类的过程中为静态变量分配内存. 类变量:static变量在内存中只有一个,存放在方法区,属于类变量,被所有实例所共享 销毁:类被卸载时,静态变量被销毁,并释放 ...
- java 静态变量生命周期(类生命周期)(转)
Static: 加载:java虚拟机在加载类的过程中为静态变量分配内存. 类变量:static变量在内存中只有一个,存放在方法区,属于类变量,被所有实例所共享 销毁:类被卸载时,静态变量被销毁,并释放 ...
- Android开发工程师文集-Activity生命周期,启动方式,Intent相关介绍,Activity详细讲解
前言 大家好,给大家带来Android开发工程师文集-Activity生命周期,启动方式,Intent相关介绍,Activity详细讲解的概述,希望你们喜欢 Activity是什么 作为一个Activ ...
- react篇章-React State(状态)-将生命周期方法添加到类中
将生命周期方法添加到类中 在具有许多组件的应用程序中,在销毁时释放组件所占用的资源非常重要. 每当 Clock 组件第一次加载到 DOM 中的时候,我们都想生成定时器,这在 React 中被称为挂载. ...
- Activity具体解释(生命周期、启动方式、状态保存,全然退出等)
一.什么是Activity? 简单的说:Activity就是布满整个窗体或者悬浮于其它窗体上的交互界面. 在一个应用程序中通常由多个Activity构成,都会在Manifest.xml中指定一个主的A ...
- C语言 遍历流程 变量生命周期
来自c程序设计 谭浩强 程序编译流程 运行c程序的步骤 在编好一个c程序后.怎样上机进行编译运行呢?一般要经过一下几个步骤: 上机输入和编辑源程序.通过键盘和计算机输入程序,如果发现有错误,要及时改正 ...
- 面向过程—面向对象(C++的封装,this)_内存四区_变量生命周期
1.面向对象主要涉及 构造函数.析构函数.虚函数.继承.多态等. 2.对各种支持 的底层实现机制 c语言中,数据 和 处理数据的操作(函数) 是分开来声明,即语言本身并没有支持 “数据和函数”的关联 ...
- 线程:生命周期、实现方式、start()和run()的区别!
1.线程的生命周期 要想实现多线程,必须在主线程中创建新的线程对象.Java语言使用Thread类及其子类的对象来表示线程,在它的 一个完整的生命周期中通常要经历如下的五种状态: 新建:当一个Thre ...
- 2.Spring的Bean生命周期和组装方式
1.Spring IoC容器概述 Spring IoC容器: Spring容器即体现了IoC原理 Spring容器通过读取配置元数据负责对Beans实例化.配置和装配 配置元数据可以用X ...
随机推荐
- SQL表连接
背景 在上次的自考科目<数据库系统原理>中.已经接触到了关于数据库表连接的一些知识,近期的学习过程中又用到了关于数据库表的连接问题,趁此再跟大家一起回想一下. 导图总结 首先用一张思维导图 ...
- ArcGIS API for Silverlight 编辑Geometry
概述 ArcMap的编辑功能是非常强大的,ArcEngine编写的CS程序也可以用到ArcMap中提供的编辑功能,那么ArcGIS API forSilverlight针对Geometry的编辑提供了 ...
- mysql监控、性能调优及三范式理解
原文:mysql监控.性能调优及三范式理解 1监控 工具:sp on mysql sp系列可监控各种数据库 2调优 2.1 DB层操作与调优 2.1.1.开启慢查询 在My.cnf文件中添加如 ...
- 使用Vim或Codeblocks格式化代码
在网上的代码,有很多的代码都是丢失缩进的,几行还好,手动改改,多了呢,不敢想象,没有缩进的代码.别说排错,就是阅读都是困难的,还好,有两个常用工具可以轻松的解决问题. (一)Vim(简单方便,可将代码 ...
- VBOX安装Centos设置分辨率为1366x768[已解决]
最近想了解下GTK+,但是对于直接在系统上搭建环境有点心里阴影,怕又把桌面玩挂,所以打算在虚拟机中先试试 本来打算使用Fedora的,怕gnome太吃资源所以下了个xfce的,不过貌似有BUG,无法安 ...
- 工欲善其事:编辑器之神Vim(一)
本篇文章收集了Vim最常用和实用的一些命令,掌握这些命令就可以使用Vim了 本文仅列举个人认为常用的命令,本系列文章更像是自己的学习笔记,而不是VIM使用教程. 如果你想了解vim的更多,可以看看Co ...
- 扩展ToolBarManager、ListView和Grid控件以实现气球式的ToolTip
原文:扩展ToolBarManager.ListView和Grid控件以实现气球式的ToolTip infragistics是全球领先的UI工具和用户体验的专家,Infragistics开发了一系列的 ...
- 自己写RTPserver——大约RTP协议
自己写RTPserver--大约RTP协议 本文将带领你一步一步地实现一个简单的手RTP变速器server,旨在了解RTP流媒体传输协议以及有关多媒体编解码器的一些知识. RTP协议的必备知识 要动手 ...
- DevExpress中GridView Excel下载
DevExpress中GridView提供了许多Excel下载的方法,如gridView.ExportToExcelOld(sfdExcelDown.FileName); 在修改Bug时,遇到这样问题 ...
- 松瀚SN8P2711 2722 ADC初始化程序及应用--汇编源码
/* 松瀚 SN8P2711 2722 ADC初始化程序 及应用实例 */ INIT_ADC: MOV A, #0XB2 // 启动ADC电路 使能AIN通道 B0MOV ADM, A MOV A,# ...