前言
计算机程序在存储数据时必须要跟踪的三种基本属性:
1.信息存储在何处。
2.存储的值为多少。
3.存储的信息类型。
对于在声明指针时,顺便说说 *运算符(间接值或解除引用运算符)两边的空格是可选的。
传统上,c语言程序猿喜欢这样干:
int *p;
(这里强调的是 *p 是一个int类型的值)
而很多c++的埼玉喜欢这种格式:
int* p;
(这里强调的是:int* 是一种类型–指向int的指针。)
但是对于编译器而言,有无空格是没有区别的,你甚至可以这样做: int*p;
这里讲是因为我们需要有一个良好的编程习惯。
new-分配内存
普通变量是在编译时分配的有名称的内存,而指针的作用就是通过名称去访问内存提供了一个别名。
而指针的真正的用武之地是—通过指针访问在运行阶段分配的没有名称的空间。
熟悉c语言的童鞋应该知道可以通过 malloc()库函数来在运行阶段分配内存。在c++中同样可以使用malloc,但有更方便的 new运算符。
通用格式:
typeName * pointer_name=new typeName
我们需要指定类型,那这样可以吗?
int a;
int *p=new a;
a变量已经指定了类型,但是这是错误的。
记住:typeName只能是 基本类型或者结构
注:常规变量的值都存储在栈(stack)中,而通过new的变量是从堆或者(自由存储区)分配内存。
delete-释放内存
程序员通过new得来的内存(不知道可不可new一个对象?),必须要用 delete运算符 来释放内存。
一般格式:
delete pointer_name;
例:
int *p=new int;
....
delete p;
我们要注意五点:
1.这将释放指针p指向的内存,但是并不会删除指针p本身。(这里建议释放内存过后,将指针p指向合法的内存,防止野指针。)
2.一定要配对使用 new ,delete ,否则会发生 内存泄漏,就是该内存区域再也无法使用。
3.不要释放已经释放了的内存块。
4.不要用delete释放用声明变量获得的内存。
5.对空指针使用delete是安全的。
注:一般不要创建两个指向同一块内存的指针,因为这可能会增大二次释放内存的机率。
使用new创建动态数组
我们在之前是通过声明创建的数组,这样的数组是在编译时分配内存,不管程序最终是否使用数组,数组都在那,占用了内存。这种分配内的方式称为**静态联编**。
但是我们可以使用new来创建数组,此时数组称为动态数组。 如果在程序运行阶段,需要数组,就创建数组;还可以在运行阶段,指点数组的长度。这种方式称为**动态联编**。
静态联编时,必须在编写程序时指定数组的长度。
动态联编时,可以在程序运行时确定数组的长度。
例:创建一个包含10个元素的int型的数组。
int *p=new int [10];
注:不要在new后面画蛇添足,加上一个数组名。
通用格式:
typeName * pointer_name=typeName [array_size ];
new运算符返回的是第一个元素的地址,在这,该地址返回给了指针p。
但是对于用delete释放通过new得到的数组时,我们采用的另一种格式:
delete [] p;
方括号告诉程序,应该释放整个数组,而不是指针p指向的元素。
**注:**对于访问动态数组的元素,可以看看这篇博客: 点这里.
声明获得内存 vs new获得内存
我们通过声明获得的内存空间是在栈中存储的;
我们通过new获得内存往往是在堆(自由存储区)中存储的。数据的生命周期是不受函数和程序的生命周期控制的。所以程序员通过new和delete 对想要的数据和内存有了更大的控制权。
但是在栈中,自动添加的和自动删除的使得内存总是连续的,但是通过new得来的内村导致占用的自由存储区不连续。所以跟踪这块内存就相对困难。况且还容易因为我们的疏忽导致内存泄漏。