数组与指针

数组


        在表达式中使用数组名时,该名字会自动转换为指向数组第一个元素的指针。在使用下标访问数组时,实际上是对指向数组元素的指针做下标操作。在指针上加上一个整形数值,其结果仍然是指针。对数组名取地址,返回一个指向数组的指针,此时指针的算术运算单位为sizeof(数组长度)。

int a[N];
int* p;
p = &a;  //a[index] equivalent to *(p+index)

        因为数组不能复制,所以无法编写使用数组类型形参的函数。数组会被自动转化为指针,所以处理数组的函数通常通过操纵指向数组中的元素的指针来处理数组。通常,将数组形参直接定义为指针比使用数组语法定义要好。这样就明确地表示,函数操纵的是指向数组元素的指针,而不是数组本身。由于忽略了数组长度,形参定义中如果包含了数组长度则特别容易引起误解。当编译器检查数组形参关联的实参时,它只会检查实参是不是指针、指针的类型和数组元素的类型是否匹配,而不会检查数组的长度。

        Hunger:

  • 二维数组,即数组的数组,即数组指针
  • 二维指针,即指针的指针,即指针数组
  • 设有二维数组 type a[][],则数组名a是一个指针,类型为type(*)[],a+i为与a同类型的指针;而a[i]也是一个指针,其类型为type*。a+i和a[i]指向同一个地址(输出一样),但指向的类型不一样,故解引用*(a+i)和*a[i]的类型不一样(输出不一样),*(a+i)的类型为type*,*a[i]的类型为type。


动态数组

        动态分配数组时,如果数组元素具有类类型,将使用该类的默认构造函数实现初始化;如果数组元素是内置类型,则无初始化。

        动态分配的内存最后必须进行释放,否则内存最终将逐渐耗尽。如果不在需要使用动态创建的数组,程序员必须显式地将其占用的存储空间返回给程序的自由存储区。C++语言为指针提供delete []表达式释放指针所指向的数组空间。该语句回收了指向的数组,把相应的内存还给自由存储区。在关键字delete和指针之间的空方括号对是必不可少的,它告诉编译器该指针指向的是自由存储区中的数组,而并非单个对象。遗漏空方括号对是一个编译器无法发现的错误,将导致程序在运行时出错。

        理论上,回收数组时缺少空括号对,有可能会导致运行时少释放了内存空间,从而产生内存泄漏(memory leak)。对于某些系统和/或元素类型,有可能会带来更严重的运行时错误。

delete 和 delete []的真正区别



内存泄漏

        内存泄漏也称作“存储渗漏”,用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。(其实说白了就是该内存空间使用完毕之后未回收)即所谓内存泄漏。
        内存泄漏形象的比喻是“操作系统可提供给所有进程的存储空间正在被某个进程榨干”,最终结果是程序运行时间越长,占用存储空间越来越多,最终用尽全部存储空间,整个系统崩溃。所以“内存泄漏”是从操作系统的角度来看的。这里的存储空间并不是指物理内存,而是指虚拟内存大小,这个虚拟内存大小取决于磁盘交换区设定的大小。由程序申请的一块内存,如果没有任何一个指针指向它,那么这块内存就泄漏了。

        从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到。



指针


Blog:https://github.com/xuelangZF/CS_Offer/blob/master/C%2B%2B/Pointer.md


        *操作符(解引用操作符)将获取指针所指的对象,x[i]等效于*(x+i)。

        给引用赋值修改的是该引用所关联的对象的值,而不是使引用与另一个对象关联。当引用初始化后,只要该引用存在,它就保持绑定到初始化时指向的对象,不可能将引用绑定到另一个对象。

        Hunger:指针ptr1-ptr2的实际运算是(ptr1-ptr2)/sizeof(address length)。


管理指针成员

        (类)指针成员默认具有与指针对象同样的行为。然而,通过不同的复制控制策略,可以为指针成员实现不同的行为。大多数C++类采用以下三种方法之一管理指针成员:

  • 指针成员采取常规指针行为,这样的类具有指针的所有缺陷但无需特殊的复制控制;
  • 类可以实现所谓的“智能指针”行为,指针所指向的对象是共享的,但类能够防止悬垂指针;
  • 类采取值型行为,指针所指的对象是唯一的,由每个类对象独立管理。

智能指针
        定义只能指针的通用技术是采用一个使用计数(use count),有时也称为引用计数(reference count),智能指针类将一个计数器与类指向的对象相关联。使用计数跟踪该类有多少个对象共享同一个指针。使用计数为0时,删除对象。
  • 每次创建指针类的新对象时(定义一个新的指针),初始化指针并将使用计数置为1;
  • 当对象作为另一个对象的副本而创建时,复制构造函数复制指针并增加与之相应的使用计数的值;
  • 对一个对象进行赋值时,赋值操作符减少左操作数所指对象的使用计数的值(左操作数即指针指向另一个对象了,且如果使用计数减至0,则删除对象),并增加右操作数所指对象的使用计数的值;
  • 调用析构函数时,析构函数减少使用计数的值,如果计数减至0,则删除基础对象。

auto_ptr

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值