有点疑惑,c++中int*p=new int[0]动态分配了多大的内存,求不吝赐教
int main()
{
int *ptr=new int[0];
ptr[0]=1;
ptr[1]=2;
cout<<"ptr[0]:"<<ptr[0]<<endl;
cout<<"ptr[1]:"<<ptr[1]<<endl;
for(int i=0;i<6;i++)
{
ptr[i]=i+1;
}
for(int i=0;i<6;i++)
{
cout<<ptr[i]<<"\t";
}
cout<<endl;
system("pause");
return 0;
}
访问ptr[6]程序会中断,疑惑new int[0]分配了多大的空间,在什么情况下会访问越界,在vs2013下编译的
new分配的时候,一般会分配除了它本身大小以外的内存头和内存尾,一般形式为:[内存头][可用数据][内存尾]。
而你的ptr指针返回的是[可用数据]部分的起始地址。大部分编译器在用户分配的size为0的情况下,会自动分配1字节的可用内存,
以保证返回的ptr是一个合法的指针。但是,C/C++是一个从来都不校验内存溢出的语言。因此,你可以访问任意从ptr开始的地址的数据,
如果你访问的地址正巧有数据,则这个数据就会被访问到,如果正好这个地址没分配数据,才会抛出异常。但是如果你在ptr指向的任意地址
中写了数据,且地址已经超过了可用数据的范围,则会有两种情况发生:如果该地址没有分配数据,则你很幸运,系统会直接抛出异常。
如果该地址有数据(比如内存尾或其他分配的数据),则会让你写入,并不报任何错误,但是在程序运行到需要读取你写的数据部分时候会发生
你所以为的莫名其妙的错误。这时候要去排查错误,那可真是想死的心都有了。这也是C/C++中最难控制的部分。
new int[0] 没有意义,是错误的。C++里没有规定会怎样。就算在vs2013下编译运行了读写ptr[5]没问题,不代表其他平台如gcc、vs2015没问题。
读写ptr[x]行为就是未定义的,在vs2013中,你如果编译的是release,可能也会挂掉。
new int[0] 不分配内存,也没意义
new int[0]表示分配的数组长度为0,既不分配内存。
动态创建new 0是不分配内存的
new int[0] 0没有分配内存
只是地址指向,不会分配内存!
我在思考这个问题的时候的思路。int*pt 是创建了一个指向int类型的指针,new int,new在内存中找到一块new大小的内存将其地址分配给指针pt。我创建数组int a[0],输出sizeof(a),要知道C++中数组名即相当于数组第一个元素的位置也相当于整个数组的指针,结果输出为0,即创建了一个空数组,数组大小为0。所以我初步认为int*pt = new int[0]未分配任何内存。如果这样写这条语句则不再符合C++动态分配内存这个概念在实际编程中的应用。
首先感谢以上各位不为分数的无私赐教。int *ptr=new int[0] 这是一条无意义语句,系统并没有分配可用的空间,所以ptr指针指向的地址是随机的,和定义了一个指针却没有赋初值是一样的。程序执行的结果并不能说明什么问题。提出这个问题是在 练习复制构造函数的时候:
classname (const classname &obj) {
this->num=obj.num;
if(obj.pName!=NULL)//这里必须要做这样的判断,否则就会出现这样的问题
{
this->pName= new int[num];
}
eles
{
this->pName=NULL;
}
}