关于new(C++)和malloc(C)

c++中new运算符从堆区分配一段存储空间:

char *pb=new char[1024];
char *pa=(char *)malloc(1024*sizeof(char));

从堆区分配连续的1024*sizeof(char)大小的存储空间;该空间与栈区(即自动变量所在区域)不同,栈区有FILO(或LIFO)的特点,自动变量在代码块执行时载入,结束时出栈。而堆区是一段专门给new和C函数malloc所提供的一段存储空间。
new在堆区分配1024个char类型的空间,(一个1024个字节的char数组),pb指向该空间的首地址;对该空间的访问:pb[i]即访问该空间的第i个元素,(同数组对元素的访问),该空间最好主动释放,不然可能会造成内存泄漏,delete [] pb释放该空间。
malloc类似。free (pa) 释放空间。
接下来看如下代码:

#include<iostream>
#include<cstring>
using namespace std;

struct chaff
{
    char dross[20];
    int slag;
};

int main()
{
    char buffer[1024];
    chaff *pa=new (buffer) chaff[2];
    char *pb=new char[1024];
    chaff *pc=new (pb) chaff[2];
    int buffer_s[1024];
    int *pd=new int[1024];
    double *pe=new double[1024];


    cout<<"buffer address: "<<&buffer<<"  "<<(void *)buffer<<endl<<buffer<<endl;;
    cout<<"pa address: "<<pa<<"  "<<(void *)pa<<"  "<<&pa<<" pa[0] address: "<<&pa[0]<<endl;
    cout<<"pb address: "<<pb<<"  "<<(void *)pb<<"  "<<&pb<<endl;
    cout<<"pc address: "<<pc<<"  "<<(void *)pc<<"  "<<&pc<<" pc[0] address:"<<&pc[0]<<endl;
    cout<<"buffer_s address:"<<&buffer_s<<"  "<<buffer_s<<"  "<<(void *)buffer_s<<endl;
    cout<<"pd address: "<<pd<<"  "<<(void *)pd<<"  "<<&pd<<endl;
    cout<<"pe address: "<<pe<<"  "<<(void *)pe<<"  "<<&pe<<endl;
    delete[] pb;
    delete[] pd;
    delete[] pe;
    return 0;
}

new运算符的重载定位new运算符:

char buffer[1024];
chaff *pa=new (buffer) chaff[2];

在数组buffer中从数组首地址开始分配两个结构体chaff大小的空间【“(buffer)”可以设置偏移量,本代码设置为从首地址开始】,这段空间的首地址储存在pa中。
对于char buffer数组其首地址的打印:cout<<&buffer<<endl;或者cout<<(void *)buffer<endl;如果用cout<<buffer<<endl;则打印为数组buffer的内容即1024个空字符(空白符)。
对于new内存空间,其首地址打印:cout<<pa<<endl;pa中本来就放的内存首地址。而&pa会打印指针pa的地址。

char *pb=new char[1024];
chaff *pc=new (pb) chaff[2];

而这段代码在堆区分配内存首地址给pb后从中再分配两个chaff结构体的大小给pc;
具体地址打印如下:

buffer address: 0x7ffcc0bafb90  0x7ffcc0bafb90
pa address: 0x7ffcc0bafb90  0x7ffcc0bafb90  0x7ffcc0baeb68 pa[0] address: 0x7ffcc0bafb90
pb address:   0x1bdd010  0x7ffcc0baeb70
pc address: 0x1bdd010  0x1bdd010  0x7ffcc0baeb78 pc[0] address:0x1bdd010
buffer_s address:0x7ffcc0baeb90  0x7ffcc0baeb90  0x7ffcc0baeb90
pd address: 0x1bdd420  0x1bdd420  0x7ffcc0baeb80
pe address: 0x1bde430  0x1bde430  0x7ffcc0baeb88

可以知道,对于非char类型的数组,其首地址可以直接由数组名打印,而char类型数组直接打印将会打印其数组内容。
对buffer地址打印,必须用&buffer或者(void *)buffer打印。

pa和pc都是结构体指针,可直接打印,其内容是new空间首地址。
pb为char类型指针,指向new内存段,打印其内容必须用(void *)强制转换,否则打印pb数组内容。
buffer_s为int数组,打印其地址可用buffer_s,&buffer_s,(void *)buffer_s。
pd,pe分别是int 和double的new内存段,地址保存在pd,pe中,可用pd,pe直接打印。

综上,对于char类型数组char buffer[128],打印其地址为
cout<<&buffer<<endl;
cout<<(void *)buffer<<endl;
对于char类型的new动态存储空间char *pa=new char[128];,打印其地址为:
cout<<pa<<endl;
cout<<(void *)pa<<endl;
cout<<&pb<<endl;会打印pb指针的地址;
对于其他类型的数组 Type buffer[128];打印其地址:
cout<<buffer<<endl;
cout<<&buffer<<endl;
cout<<(void *)buffer<,endl;
对于其他类型的new动态存储空间Type *pa=new Type[128];打印其地址为:
cout<<pa<<endl;
cout<<(void *)pa<<endl;
cout<<&pa<<endl;会打印指针pa的地址;

不同于c语言中的printf()函数,它可以使用格式化控制串%d ,%c,%s,%lf…来打印相应的整型,字符,字符串,地址等。

猜你喜欢

转载自blog.csdn.net/qq_43260665/article/details/86240044