C++基础——4.7指针和自由存储空间

  • 声明和初始化指针
int a = 10;
int *b = &a; // 将pt的值设置为&b

int *p1, p1; // 一个int类型指针p1, 和一个int类型变量p2,每个指针变量名都需要一个*

在使用常规变量时,值是指定的量,而地址为派生量。在指针策略中将地址视为指定的量,而将值视为派生量

  • 指针的危险
// 在C++中创建指针时,计算机将分配用来存储地址的指针1
// ,但不会分配用来存储指针所指向的数据的内存。为数据提供空间是一个独立的步骤
long *fellow;
*fellow = 23323;
// fellow是指针,但是它指向的地址是不确定的,可能在代码段可能是其他。
// 此时将造成隐匿难以发现的bug

一定要在对指针应用解除引用运算符之前,将指针初始化为一个确定的、适当的地址。

  • 指针和数字
    虽然计算机通常把地址当做整数处理,但是指针不是整形。整数是可以执行加、减、乘、除的数字。指针描述的位置,将地址相乘是没有意义的。从对它们执行的操作来看,它们是彼此不同的,因此。不能简单的将整数赋值给指针
int *pt;
pt = 0xB8000000; // c99标准发布之前,C语言允许这样做。
// 但C++在类型一致方面要求更严格。编译器将产生类型不匹配的错误消息

// 要将数字值作为地址使用,应当使用强制类型转换将数字转换为适当的地址类型
int *pt;
pt = (int *)0xB8000000;

pt是int值的地址并不意味着pt本身的类型是int。在某些平台中,int类型是2个字节值,而地址是4个字节值

  • 使用new来分配内存 (new delete & malloc free)
    变量实际是编译时分配的有名称的内存,而指针只是为可以通过名称直接访问的内存提供了一个别名。它真正的用武之地在于,在运行阶段分配未命名的内存以存储值。在这种情况下只能通过指针来访问内存
/* typeName * pointer_name = new typeName; */
/* 在两个地方指定数据类型:用来指定需要什么样的内存和用来声明合适的指针 */

int *pt = new int;
*pt = 100;

delete pt;
/* 1. 释放ps指向的内存,但不会删除指针ps本身。可以将pt重新指向另一个新分配的内存 */

/* 2. 要配对使用new和delete;否则将发生内存泄露(memory leak)。
被分配的内存无法使用了,如果泄露严重,程序将由于不断寻找更多内存终止 */

/* 3. 不可重复释放内存块, */
int *ps = new int;
delete ps;
delete ps; // 重复释放

/* 4. 不能使用delete释放声明变量所获得的内存 */
int jugs = 5;
int *p1 = &jugs; 
delete p1; 	// not allowed, memory not allocated by new

/* 只能用delete释放使用new分配的内存, 然而对空指针使用delete是安全的 */

new分配的内存块通常与常规变量声明分配的内存不同。变量和常规指针的值都存储在栈内存,而new从堆内存或自由存储区free store分配内存

  • new创建动态数组
    对于大型数据(数组、字符串和结构)应该使用new来创建数组;new是采用动态联编(dynamic binding)的方式创建数组,是在运行阶段创建它并确定长度。而通过声明创建数组,是采用静态联编(static binding)的方式创建数组,是在编译时加入到程序中
int *arr =  new int [10];

delete [] arr;
  • 使用new和delete时,应遵守规则
    1. 不要使用delete释放不是new分配的内存
    2. 不要使用delete释放同一内存块两次
    3. 如果使用new[]位数组分配内存,则应使用delete[] 来释放
    4. 如果使用new[] 为一个实体分配内存,则应使用delete释放
    5. 对空指针应用delete是安全的

猜你喜欢

转载自blog.csdn.net/gripex/article/details/105523275