用new来分配内存吧
期待已久的new对象环节,终于要来了。
在这之前我再给自己洗个脑
星号 指针 是值
指针是地址
程序员要告诉new,需要为那种类型的变量分配内存,new将找到一个长度正确的内存块,并返回该内存块的地址。
程序员的责任是将该地址赋给一个指针。
int * pn = new int
new运算符会根据后面的数据类型来决定要开多大的空间。
通过询问和研究我认为,之所以需要new一个指针是因为,new进行内存分配是因为这样是动态的内存分配,且内存大小和存放类型是自己决定的。于是new会找到合适的内存空间并返回地址给指针变量
引用大佬的解释 加深理解
1:声明分配内存是在编译阶段进行的,new分配内存是在运行阶段进行的
2:声明被放在栈中,new被分配在堆中或自由存储区中
3:声明创建数组,在编译阶段是就为他分配内存。
使用new的原因
1.可以动态的申请空间,以便动态确定对象所需要的内存;
2.便于储存大型对象,通常情况下栈区的大小容不下过于庞大的对象;
3.传递指针比传递整个对象更方便高效;
形象解释
举几个生动形象的例子解释以上三条原因:1. 每个人都要吃盐,盐不够了再去买显然比把这辈子要吃的盐一次性买下来要明智
2.如果你是卖盐的,储存了很多盐,你只需要建一个仓库把盐放进去,然后自己记住仓库地址即可,而不需要把盐全部放在自己的家中;
3 如果要去很远的地方谈卖盐的生意,只需要选一些有代表性的信息(地址)给对方就可以了,不需要把整个仓库搬过去给对方看。
#include<iostream>
int main(){
using namespace std;
int nights = 1001;
int * pt = new int;
* pt = 1001;
cout<<"nights 的值是";
cout<<nights<<":地址"<<&nights<<endl;
cout<<"int";
cout<<"值为"<<*pt<<":地址"<<pt<<endl;
double * pd = new double;
*pd = 10000001.0;
cout<<"double 的值是";
cout<<*pd<<":地址"<<pd<<endl;
cout<<"pd指针的地址是"<<&pd<<endl;
cout<<"size of pt ="<<sizeof(pt)<<endl;
cout<<"size of *pt"<<sizeof(*pt)<<endl;
cout<<"size of pd ="<<sizeof(pd)<<endl;
cout<<"size of *pd"<<sizeof(*pd)<<endl;
return 0;
}
运行结果
nights 的值是1001:地址0x6ffe04
int值为1001:地址0xcb1530
double 的值是1e+007:地址0xcb1550
pd指针的地址是0x6ffdf8
size of pt =8
size of *pt4
size of pd =8
size of *pd8
释放内存
释放内存可以用delete
只有在new了一片内存空间之后才能用delete
例如
int * ps = new int;
delete ps;//正确的用法
delete ps;//由于ps已经被释放,再次释放可能会删除更多的内存空间,结果是不确定的
int jugs = 5;
int * pi = &jugs;//这个是放地址的指针
delete pi;//声明产生的指针不可以这样释放
delete的内容是new分配的内存,也就是说不一定要是被new的指针,而是一定要有new的地址
int * ps = new int;
int * pq = ps;
delete pq;
在这里delete删除掉的是ps内容的内存,而ps的内容地址是由new分配的。
使用new来创建动态数组
new分配动态数组是更重要的,因为小型变量往往声明就可以了。
在编译时给数组分配内存叫做静态联编,意味着数组是在编译时加入到程序中的。但是在使用new时,如果在运行阶段需要数组,则创建它,如果不需要则不创建。还可以在程序运行的过程中选择数组的长度,这被称之为是动态联编。这意味着数组是在程序运行中被创建的,所以称之为动态数组。
new创建动态数组和delete释放
int * psome = new int[10];
delete [] psome;
psome指向的是数组的首地址
写方括号是因为要告诉程序应该释放整个数组而不仅仅是指针所指向的元素。(注意new和delete的格式要匹配,不能一个带方括号一个不带)
在使用new和delete时要符合以下原则
不要使用delete来释放不是new分配的内存
不要使用delete释放同一块内存两次
如果使用new[]为数组分配内存,则应使用delete[]来释放。
如果使用new为一个实体分配内存,则应使用delete(无方括号)来释放
对空指针delete是安全的
在c和c++中指针和数组几乎可以等同使用,可以用数组名(指针名)[索引]的方法来访问数组元素。
#include<iostream>
int main(){
using namespace std;
double * p3 = new double[3];
p3[0] = 0.2;
p3[1] = 0.5;
p3[2] = 0.8;
cout<<"p3[1] 是"<<p3[1]<<".\n";
p3= p3 +1;
cout<<"现在我把p3加1了,p3[0]的值为"<<p3[0]<<endl;
cout<<"p3[1]为"<<p3[1]<<".\n";
p3 = p3 -1;
delete [] p3;
return 0;
}
运行结果
p3[1] 是0.5.
现在我把p3加1了,p3[0]的值为0.5
p3[1]为0.8.
这里面可以看出,虽然数组名不可更改,但是指针的值可以更改,如果指针加一,那么会指向数组的下一个元素。而这也取决于指针的类型,明天继续学指针运算