<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 195, comments - 34, trackbacks - 0, articles - 1

    C++ placement new 用法舉例zz

    Posted on 2010-04-20 17:15 小強摩羯座 閱讀(3805) 評論(0)  編輯  收藏 所屬分類: C++ &VC
    C++ placement new 用法舉例zz
    2009-12-17 16:16

    在處理內存分配的時候,C++程序員會用new操作符(operator new)來分配內存,并用delete操作符(operator delete)來釋放內存。這是一個new操作符的例子。

    class CTest
    {
         
    /* 成員函數和成員數據 */
    };

    // . . . 代碼

    //
    分配一個對象
    CTest * pTest = new Test;
    // 分配一個有十個對象的數組 (CTest 要有缺省構造函數(default constuctor)
    CTest * p10Tests = new Test[ 10];

    雖然這種寫法在大多數時候都工作得很好,但還是有些情況下使用new是很煩人的,比如當你想重新分配一個數組或者當你想在預分配的內存上構造一個對象的時候。

    比如第一種情況,重新分配一個數組效率是很低的:

    // 分配一個有10個對象的數組
    CTest * pTests = new Test[ 10];
    // . . .
    //
    假設現在我們需要11個對象
    CTest * pNewTests = new Test[ 11];
    // . . . 我們必須把原來的對象拷貝到新分配的內存中
    for ( int i = 0; i < 10; i++)
         pNewTests[ i] = pTests[ i];
    delete pTests;
    pTests = pNewTests;

    如果你想在預分配的內存上創建對象,用缺省的new操作符是行不通的。要解決這個問題,你可以用placement new構造。它允許你構造一個新對象到預分配的內存上:

    // buffer 是一個void指針 (void *)
    //
    用方括號[] 括起來的部分是可選的
    [CYourClass * pValue = ] new( buffer) CYourClass[( parameters)];

    下面是一些例子:

    #include <new>

    class CTest
    {
    public:
         CTest()
         {}
         CTest( int)
         {}
        
    /* 代碼*/
    };

    int main(int argc, char* argv[])
    {

         //
    由于這個例子的目的,我們不考慮內存對齊問題
         char strBuff[ sizeof( CTest) * 10 + 100];
         CTest * pBuffer = ( CTest *)strBuff;

        
    // 缺省構造
         CTest * pFirst = new(pBuffer) CTest;

        
    // 缺省構造
         CTest * pSecond = new(pBuffer + 1) CTest;
        
        
    // 帶參數的構造;
         //
    不理會返回的指針
         new(pBuffer + 2) CTest( 5);

        
    // 帶參數的構造
         CTest * pFourth = new( pBuffer + 3) CTest( 10);

        
    // 缺省構造
         CTest * pFifth = new(pBuffer + 4) CTest();

        
    // 構造多個元素(缺省構造)
         CTest * pMultipleElements = new(pBuffer + 5) CTest[ 5];
         return 0;
    }

    當你有自己的內存緩沖區或者在你實現自己的內存分配策略的時候,placement new會很有用。事實上在STL中廣泛使用了placement new來給容器分配內存;每個容器類都有一個模版參數說明了構造/析構對象時所用的分配器(allocator)。

    在使用placement new的時候,你要記住以下幾點:

    • 加上頭文件#include <new>
    • 你可以用placement new構造一個數組中的元素。
    • 要析構一個用placement new分配的對象,你應該手工調用析構函數(并不存在一個“placement delete”)。它的語法如下:

    pFirst->~CTest();
    pSecond->~CTest();

    前段事件,我問過關于placement new的問題,一位仁兄講了一些道理,他說道:

    ::棧上的對象(注意,是類對象,char類型就無需了,后面還會提到)保證放在對齊地址上. 

    但是,個人實驗了一下,發現并不是這樣

    例如:
    int main()
    {
    char c1 = 'A' ;
    char c2 = 'B' ;
    char c3 = 'C' ;
    char c4 = 'D' ;
    char c5 = 'E' ;

    //-------- 驗證這四個地址是否是 4 的倍數 --------------//
    if ( ((int)(&c1)) % 4 == 0 )
    cout << "c1:Yes" << endl ;

    if ( ((int)(&c2)) % 4 == 0 )
    cout << "c2:Yes" << endl ;

    if ( ((int)(&c3)) % 4 == 0 )
    cout << "c3:Yes" << endl ;

    if ( ((int)(&c4)) % 4 == 0 )
    cout << "c4:Yes" << endl ;

    if ( ((int)(&c5)) % 4 == 0 )
    cout << "c5:Yes" << endl ;

    cout << (int)(&c1) << endl // 輸出四個字符所在的地址(輸出結果都是 4 的倍數)
     << (int)(&c2) << endl 
     << (int)(&c3) << endl 
     << (int)(&c4) << endl 
     << (int)(&c5) << endl ;
    }
    -----------------------------
    上面的執行結果在VC下運行都是 4 的倍數
    --------------

    --> 問題1:連棧上分配的空間地址都是 4 的倍數,那就說明系統分配的空間都是 4 的倍數吧???

    --> 問題2:如果萬一,如果放一個對象的地址不是4的倍數,那么會出現什么情況??可以給簡單說一下嗎?

    --> 問題3:地址對齊的通用性???
       -------------
       程序1:
    Class C1
    {
    int i ;
    char c ;
    } ;
    cout << sizeof(C1) << endl ;// 輸出結果: 8 (是 4 的倍數)
       程序2:
    class C2
    {
    char c1 ;
    char c2 ;
    } ;
    cout << sizeof(C2) << endl ;// 輸出結果:2 ( 上一個中char類型也給了4個字節,怎么這個地方都給了一個字節??)
    --> 問題4:由上面的程序2 引出下面的程序
    class C2// sizeof(C2) =2 ,在VC實驗下的結果,不是 4
    {
    char c1 ;
    char c2 ;
    } ;
    //----------用placement new方法建立對象----------------
    void *ptr = operator new(100) ;// 分配內存
    C2 *POINTER = (C2*)ptr ;// 類型轉換
    String *str1 = new (POINTER) C2() ;// 建立一C2對象
    String *str2 = new (POINTER+1) C2() ;// 再建立一個對象
    String *str3 = new (POINTER+2) C2() ;// 再建立一個對象

    cout << (int)(str1) << endl// 結果:3608720(  是4的倍數)
          << (int)(str2) << endl // 結果:3608722(不是4的倍數)!!
                         << (int)(str3) << endl ;// 結果:3608724(不是4的倍數)!!


    主站蜘蛛池模板: 美女黄色毛片免费看| 内射无码专区久久亚洲| fc2成年免费共享视频18| 亚洲一级黄色大片| 国产亚洲精品资源在线26u| 免费国产高清视频| 大学生高清一级毛片免费| 四虎国产精品永久免费网址| 一区二区三区在线免费| 亚洲av永久无码精品网址| 亚洲国产精品免费观看| 亚洲国产综合第一精品小说| 久久精品国产精品亚洲色婷婷| 亚洲国产精品尤物YW在线观看| 德国女人一级毛片免费| 曰曰鲁夜夜免费播放视频| 中文字幕视频免费| 免费a级毛片无码a∨免费软件| 最好2018中文免费视频| 亚洲AV噜噜一区二区三区| 亚洲中文字幕一二三四区苍井空 | 美女露100%胸无遮挡免费观看| 亚洲娇小性色xxxx| 亚洲国产中文在线视频| 亚洲色图视频在线观看| 亚洲人成电影福利在线播放| 久久久久久亚洲精品中文字幕| 亚洲色大成网站www永久一区| 久久久久久久亚洲精品| 亚洲中文字幕无码专区| 中文字幕精品无码亚洲字| 国产午夜亚洲精品国产成人小说| 亚洲&#228;v永久无码精品天堂久久| 日本高清色本免费现在观看| 日韩伦理片电影在线免费观看| 精品国产免费一区二区| 日本特黄特黄刺激大片免费| 国产小视频在线免费| 亚洲午夜日韩高清一区| 亚洲婷婷五月综合狠狠爱| 亚洲AV午夜福利精品一区二区|