• LeekinDeveloper@Gmail.com

C++ new和指针


C++ new和指针

这是一个装饰图

计算机在储存数据时我们必须跟踪三个属性:

  • 信息被储存在何处?
  • 储存的值是多少?
  • 储存的信息是什么类型
  1. 声明一个指针
    1
    2
    int a=100;
    int *b=&a;

这里我们创建了a变量和指针b,并把a的地址赋给指针b,现在指针b储存的就是a在内存里的地址,我们可以通过b来访问a的值:

1
2
a和 *b是等效的,他们的值都是100
&a和b是等效的,它们都是内存地址

  1. 指针和C++运行原理
    oop强调的是运行阶段进行决策,运行阶段是指程序运行时,编译阶段是指编译器把程序组合起来,变成二进制文件,比如我们要创建一个数组,但是我们不知道数组在使用的时候要存多少数据,这时候不能把他的容量写死,而是让它在运行阶段根据实际情况来决定他的大小,例如:

    1
    2
    int a[20];//编译阶段分配19的固定大小内存
    int a[]=new int;//运行阶段分配内存
  2. 指针详细介绍

    1
    int *a; //指针名:a,指针指向的类型为:int,指针类型为:int *
  3. 指针的危险

    我们在创建指针时,计算机将分配用来储存地址的内存,但不会分配用来存储指针所指向的数据的内存,为数据提供空间是一个独立的步骤,如果忽略这一步骤将导致不可预测的后果。

    1
    2
    long *fellow;
    *fellow=223323;

上述代码没有将地址赋给指针,223323将被存在何处我们不得而知,由于fellow没有被初始化,它可能有任何的值,不管地址是什么,他将是储存223323的地址,如果fellow恰巧为1200,计算机将把数据储存在地址1200上,fellow所指向的地方可能并不是所要储存223323的地方,这种错误将导致不可预测的后果。

注意:一定要在对指针解除引用运算符(*)之前,将指针初始化为一个确定的、适合的地址

  1. 使用new来分配内存

    在C语言中使用库函数malloc()函数来申请内存,C++同样也可以使用他,但是C++有更好的方法–new运算符,其实new运算符是在堆内存(heap)当中来申请内存,内存分为堆内存(heap)和栈内存(stack),以其他方式申请的内存都放到了栈内存中,申请和释放都由系统来完成,而堆内存则需要我们手动申请、释放。

    1
    int *ptr=new int;

new int告诉程序,需要一块能够储存int大小的内存块,new根据类型来确定需要多少字节的内存,然后它找到这样的内存,并返回其地址,接下来地址会被赋给ptr。

  1. new和delete

    在前面我们已经说过,heap内存需要我们手动申请和释放,我们已经学会如何来申请内存,那么释放呢?

    1
    2
    delete ptr;//删除内存占用
    ptr=NULL;//将指针置为空(安全起见)

对于使用new新建的数组应该怎样来释放内存

1
2
3
int *some=new some[];
/*使用some数组*/
delete []some;

这里我们使用new来为some数组申请内存,对应就应该使用delete []some来释放内存,而不是使用delete some,这仅仅只清理了数组地一个元素所占的内存,及some[0],内存依然没有被清理干净,同样会发生内存泄漏的危险。

  1. 数组与指针
    在C++中,数组在内存中是一个连续的片段,文章的开头我们已经说了,我们需要跟踪他的三个属性,其中我们不确定它在内存中的位置,因为数组的每个元素都有其地址。其实数组也是一个指针,当声明一个数组的时候,就以它的第一个元素的地址来作为他在内存当中的位置,比如:
    1
    double price [];

这里的price和指针是一样的,加入我们试图输出price:std::cout<<price;这里将会输出一个内存地址,也就是说,数组就是指针。