new限定區域分配內存

#include <iostream>
#include<stdio.h>
#include <new>//需要添加該頭文件

using namespace std;
const int ARRLEN = 100;
int static_buf[ARRLEN];//靜態區
const int N = 5;
int main()
{
    int *p1,*p2;

    cout<<"static_buf address:"<<static_buf<<endl;
    for(int j = 0; j < 3; j++)
    {
        cout<<"\n\n\n";
        p1 = new int[N];
        p2 = new (static_buf)int[N];//指定區域分配內存
        for(int i = 0; i < N; i++)
        {
            p1[i] = p2[i] = i;
            cout<<"p1-->"<<&p1[i]<<"   value:"<<p1[i]<<"  ";
            cout<<"p2-->"<<&p2[i]<<"   value:"<<p2[i]<<endl;//打印出每個元素的地址和值
        }
    }
    return 0;
}


運行結果如圖:

可見,經過三次循環後p2指向的數組的地址並沒有改變,而且該地址就是在靜態存儲器中分配的static_buf的地址。這說明我們可以通過new的這種語法對已經存在的內存區域上構造數據。而且我們可以發現new不僅僅可以在堆中分配內存,而且可以使用靜態存儲區中的內存。但是這樣p1指向的內存會產生泄露,所以修改代碼:

#include <iostream>
#include<stdio.h>
#include <new>//需要添加該頭文件

using namespace std;
const int ARRLEN = 100;
int static_buf[ARRLEN];//靜態區
const int N = 5;
int main()
{
    int *p1,*p2;

    cout<<"static_buf address:"<<static_buf<<endl;
    for(int j = 0; j < 3; j++)
    {
        cout<<"\n\n\n";
        p1 = new int[N];
        p2 = new (static_buf)int[N];//指定區域分配內存
        for(int i = 0; i < N; i++)
        {
            p1[i] = p2[i] = i;
            cout<<"p1-->"<<&p1[i]<<"   value:"<<p1[i]<<"  ";
            cout<<"p2-->"<<&p2[i]<<"   value:"<<p2[i]<<endl;//打印出每個元素的地址和值
        }
        delete[] p1;//爲避免內存泄露,釋放掉p1指向的內存
    }
    return 0;
}


運行結果如圖:

可見,現在每次delete掉p1,再次new後,數組的內存地址是一樣的。

所以我們應該可以根據這個區別來判斷是否發生了內存泄露。如果程序請求分配一塊堆內存,應該是根據堆的內存指針來決定所分配內存的地址的,如果這塊內存已經delete掉了,那麼第二次分配的內存地址應該和第一次的地址一樣(假設中間沒有任何內存操作,不考慮其他程序干擾)。

 

總結一下:

1.p1存在棧中,存儲的地址指向堆。

p1需要手動釋放。

 

p2存在棧中,存儲的地址指向靜態區。

p2自動釋放。避免了內存泄露,犧牲了內存訪問的獨立性(第二次new的時候,第一次new產生的數據的沒了)。

 

2.由於p2的這種特性,所以本例中的static_buf一般在工程應用中作爲一個緩衝區。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章