zoukankan      html  css  js  c++  java
  • 探讨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次没有失效。

     

    为什么?

     

    大家可以先思考,有想法可以留言指出。限于篇幅,笔者的下一篇博客将给出具体的分析。

     
     
    分类: 编程语言
  • 相关阅读:
    操作系统--怎么实现中断
    操作系统中的描述符和GDT
    使用汇编语言实现memcpy
    Redis命令之setbit
    java webService 服务端的创建 和 客户端代码的生成与使用
    springbooot 项目读取yml配置文件(自定义)
    java自定义注解的使用(校验)
    mysql使用存储过程快速插入百万条数据
    springboot项目集成Mybatisplus配置和使用
    mysql 创建函数的过程和使用
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3147165.html
Copyright © 2011-2022 走看看