new限定区域分配内存

来源:互联网 发布:数据库无法写入中文 编辑:程序博客网 时间:2024/05/16 05:05
#include <iostream>#include<stdio.h>#include <new>//需要添加该头文件using namespace std;cons    t 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;    }    return 0;}

运行结果为:
这里写图片描述

可见,现在每次delete掉p1,再次new后,数组的内存地址是一样的。
所以我们应该可以根据这个区别来判断是否发生了内存泄露。如果程序请求分配一块堆内存,应该是根据堆的内存指针来决定所分配内存的地址的,如果这块内存已经delete掉了,那么第二次分配的内存地址应该和第一次的地址一样(假设中间没有任何内存操作,不考虑其他程序干扰)。
 
总结一下:
1.p1存在栈中,存储的地址指向堆。
p1需要手动释放。
 
p2存在栈中,存储的地址指向静态区。
p2自动释放。避免了内存泄露,牺牲了内存访问的独立性(第二次new的时候,第一次new产生的数据的没了)。
 
2.由于p2的这种特性,所以本例中的static_buf一般在工程应用中作为一个缓冲区。