C++内存分配
===================================
静态分配: 编译器在处理程序源代码时分配。
在程序执行前分配,因此效率比较高。
但是它要求在程序执行之前就知道所需内存的类型和数量,因此缺少灵活性。
如:
int ival = 1024; //指示编译器分配足够的存储区以存放一个整型值,
//该存储区与名字ival相关。并用数值1024来初始化该存储区。
动态分配: 程序执行时调用运行时刻库函数来分配。
有两个值与一个对象相关:一个是它包含的值,另一个是存放这个值的存储区的地址。
C++支持用指针类型来存放对象的内存地址值。
如: int *pint; //声明一个指向int类型的指针
pint = &ival; //取地址操作符(&)用于对象前时,返回的是对象的地址值
*pint = *pint + 1; //解引用操作符(*)用于指针前时,返回的是指针所指的对象
等价于 ival = ival + 1;
在C++中指针的主要作用是管理和操纵动态分配的内存。
静态与动态内存分配的两个主要区别是:
1. 静态对象是有名字的变量,我们直接对其进行操作。而动态对象是没有名字的变量,我们通过指针间接对其进行操作。
2. 静态对象的分配和释放由编译器自动处理。而动态对象的分配与释放,必须由程序员显式的管理。它是由new和delete两个表达式来完成。
int *pint = new int(1024); //分配int类型的对象,对象初始值为1024
int *pia = new int[4]; //分配特定类型和维数的数组,pia拥有四元素数组的第一个元素的地址。
delete pint; //删除单个对象
delete [] pia; //删除一个数组对象
====================================
C++中的成员操作符:
====================================
用于类对象的点操作符(.)
IntArray myArray; //定义一个IntArray类的对象
int min_val = myArray.min(); //使用对象去访问类的成员函数
用于类对象指针的箭头操作符(->)
IntArray *pArray = new IntArray; //定义一个IntArray类的指针
int max_val = pArray –> max(); //使用指针去访问类的成员函数
================================
指针类型
================================
指针的典型用法是构建一个链接的数据结构,例如树(tree)和链表(list),并管理在程序执行过程中动态分配的对象,以及作为函数参数类型,主要用来传递数组或大型的类对象。
- 指针不能持有非地址值。
int ival = 1024;
int *pi = ival; //错误: pi被赋予int值ival
- 指针不能被初始化或赋值为其他类型对象的地址值。
double dval;
double *pd = &dval;
pi = pd; //错误: 无效的类型赋值
pi = &dval; // 错误: 无效的类型赋值
- C++提供了一种特殊的指针类型来支持这种需求: 空类型指针(void*)它可以被任何数据指针类型的地址值赋值(函数指针不能赋值给它)。
// ok: void* 可以持有任何指针类型的地址值
void *pv = pi;
pv = pd;
void*表明相关的值是个地址,但该地址的对象类型不知道。我们不能够操作空类型指针所指向的对象,只能传送该地址值或将它与其他地址值作比较。
==================================
指针算术运算(pointer arithmetic)
==================================
对指针的地址值增加或减少一个整数值,就叫做指针的算术运算。
指针加2意味着给指针持有的地址值位移了该类型两个对象的长度。 例如,假设一个char 是一个字节,一个int 是4 个字节,double 是8 个字节,那么指针加2是给其持有的地址值增加2、 8 还是16, 完全取决于指针的类型是char、 int 还是double。
实际上只有指针指向数组元素时我们才能保证较好地运用指针的算术运算。因为一般的变量我们不能保证它们连续的存储在内存中,因此加2 后可能不能产生一个有效的地址。指针算术运算的典型用法是遍历一个数组。例如:
int ia[ 10 ]; int *iter = &ia[0]; int *iter_end = &ia[10]; while ( iter != iter_end ) { do_something_with_value( *iter ); ++iter; // 现在iter指向下一个元素 }