探討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程序的區別(二)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM