C++:指针和new,delete详解

文章目录

    • 前言
    • new-分配内存
    • delete-释放内存
    • 使用new创建动态数组
    • 声明获得内存 vs new获得内存

前言

计算机程序在存储数据时必须要跟踪的三种基本属性:
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得来的内村导致占用的自由存储区不连续。所以跟踪这块内存就相对困难。况且还容易因为我们的疏忽导致内存泄漏。

你可能感兴趣的:(C++,指针,c++,内存管理)