C++ 定位new運算符


這里說的定位new運算符,是一種相對於普通的new運算符,可以指定內存地址的運算符,程序直接使用我們提供的地址,不管它是否已經被使用,而且可以看到新值直接覆蓋在舊值上面。

定位new運算符直接使用傳遞給它的地址,它不負責判斷哪些內存單元已被使用,也不查找未使用的內存塊

由於本質上定位new運算符並不開辟新的內存,也就不應該用delete去釋放它

單來說就是new運算符只是返回傳遞給它的地址,並將其強制轉換為void *,以便能夠賦給任何指針類型。

#include<iostream>
#include<string>

using namespace std;

const int BUF = 512;

class JustTesting
{
private:
    string words;
    int number;
public:
    JustTesting(const string& s = "Just Testing", int n = 0)
    {
        words = s;
        number = n;
        cout << words << " constructed" << endl;
    }
    ~JustTesting()
    {
        cout << words << " destroyed" << endl;
    }
    void show() const
    {
        cout << words << " ," << number << endl;
    }
};

int main()
{
    char* buffer = new char[BUF];
    JustTesting *pc1, *pc2;
    pc1 = new(buffer)JustTesting;
    pc2 = new JustTesting("Heap1", 20);
    cout << "Memory block address" << endl << "buffer: " << (void*)buffer << "     heap: " << pc2 << endl;
    cout << pc1 << ": ";
    pc1->show();
    cout << pc2 << ": ";
    pc2->show();

    JustTesting *pc3, *pc4;
    //pc3 = new (buffer)JustTesting("Bad Idea", 6); //pc3直接占用了pc1的內存區域,這樣一來如果pc1中有new分配的成員變量,將造成內存泄漏,
    //因此更好的方式是
    pc3 = new (buffer+sizeof(JustTesting)) JustTesting("Better Idea",6);
    pc4 = new JustTesting("Heap2", 10);

    cout << "Memory Contents" << endl;
    cout << pc3 << ": ";
    pc3->show();
    cout << pc4 << ": ";
    pc4->show();
        
    delete pc2;
    delete pc4;
    //由於delete buffer並不會出發buffer內對象的析構函數,所以只能手動調用其析構函數
    //需要注意調用析構函數的順序,由於晚創建的對象可能依賴早創建的對象,因此析構的順序應該與創建順序相反,另外,僅當析構了所有對象之后,才能釋放用於存儲這些對象的緩沖區
    pc3->~JustTesting();
    pc1->~JustTesting();
    delete[] buffer;
    //delete pc1; 因為buffer和pc1實際上指向同一個地址,因此如果注釋掉上面一行,打開這里,也可以正常運行,但邏輯上卻是沒有道理的
    cout << "done" << endl;
    cin.get();
    return 0;
}

 


免責聲明!

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



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