C++ new和指针

计算机在储存数据时我们必须跟踪三个属性:
- 信息被储存在何处?
- 储存的值是多少?
- 储存的信息是什么类型
- 声明一个指针
1
2int a=100;
int *b=&a;
这里我们创建了a变量和指针b,并把a的地址赋给指针b,现在指针b储存的就是a在内存里的地址,我们可以通过b来访问a的值:
1
2 a和 *b是等效的,他们的值都是100
&a和b是等效的,它们都是内存地址
指针和C++运行原理
oop强调的是运行阶段进行决策,运行阶段是指程序运行时,编译阶段是指编译器把程序组合起来,变成二进制文件,比如我们要创建一个数组,但是我们不知道数组在使用的时候要存多少数据,这时候不能把他的容量写死,而是让它在运行阶段根据实际情况来决定他的大小,例如:1
2int a[20];//编译阶段分配19的固定大小内存
int a[]=new int;//运行阶段分配内存指针详细介绍
1
int *a; //指针名:a,指针指向的类型为:int,指针类型为:int *
指针的危险
我们在创建指针时,计算机将分配用来储存地址的内存,但不会分配用来存储指针所指向的数据的内存,为数据提供空间是一个独立的步骤,如果忽略这一步骤将导致不可预测的后果。
1
2long *fellow;
*fellow=223323;
上述代码没有将地址赋给指针,223323将被存在何处我们不得而知,由于fellow没有被初始化,它可能有任何的值,不管地址是什么,他将是储存223323的地址,如果fellow恰巧为1200,计算机将把数据储存在地址1200上,fellow所指向的地方可能并不是所要储存223323的地方,这种错误将导致不可预测的后果。
注意:一定要在对指针解除引用运算符(*)之前,将指针初始化为一个确定的、适合的地址
- 使用new来分配内存
在C语言中使用库函数malloc()函数来申请内存,C++同样也可以使用他,但是C++有更好的方法–new运算符,其实new运算符是在堆内存(heap)当中来申请内存,内存分为堆内存(heap)和栈内存(stack),以其他方式申请的内存都放到了栈内存中,申请和释放都由系统来完成,而堆内存则需要我们手动申请、释放。
1
int *ptr=new int;
new int告诉程序,需要一块能够储存int大小的内存块,new根据类型来确定需要多少字节的内存,然后它找到这样的内存,并返回其地址,接下来地址会被赋给ptr。
- new和delete
在前面我们已经说过,heap内存需要我们手动申请和释放,我们已经学会如何来申请内存,那么释放呢?
1
2delete ptr;//删除内存占用
ptr=NULL;//将指针置为空(安全起见)
对于使用new新建的数组应该怎样来释放内存
1 | int *some=new some[]; |
这里我们使用new来为some数组申请内存,对应就应该使用delete []some来释放内存,而不是使用delete some,这仅仅只清理了数组地一个元素所占的内存,及some[0],内存依然没有被清理干净,同样会发生内存泄漏的危险。
- 数组与指针
在C++中,数组在内存中是一个连续的片段,文章的开头我们已经说了,我们需要跟踪他的三个属性,其中我们不确定它在内存中的位置,因为数组的每个元素都有其地址。其实数组也是一个指针,当声明一个数组的时候,就以它的第一个元素的地址来作为他在内存当中的位置,比如:1
double price [];
这里的price和指针是一样的,加入我们试图输出price:std::cout<<price;这里将会输出一个内存地址,也就是说,数组就是指针。