C++学习笔记18:指针和自由存储空间

目录

一、基本概念

二、声明和初始化指针

三、使用 new 来分配内存

四、使用 delete 来释放内存

五、使用 new 来创建动态数组

1.创建动态数组

2.使用动态数组


一、基本概念

        指针是一个变量,其存储的是值的地址,而不是值本身。通过对变量应用地址运算符(&)就可以获得它的地址,示例程序如下:

//address.cpp -- 使用地址运算符&来获取变量值的存储地址,例 &variablename
#include <iostream>
using namespace std;

int main()
{
	int donuts = 6;
	double cups = 4.5;

	cout << "donuts value = " << donuts;
	cout << " and donuts address = " << &donuts << endl;
	cout << "cups value = " << cups;
	cout << " and cups address = " << &cups << endl;

	return 0;
}

        指针变量中存储的是地址信息,对指针变量应用间接值(又称解除引用)运算符(*),可以得到该地址处存储的值,示例程序如下(该程序还演示了如何声明指针):

//pointer.cpp -- 指针变量
#include <iostream>
using namespace std;

int main()
{
	int updates = 6;             //声明一个整型变量
	int * p_updates;             //声明一个指针变量,*运算符被称为间接值或解除引用运算符
	p_updates = &updates;        //获取地址赋给指针

	//用两种方式表达值
	cout << "Value: updates = " << updates;
	cout << ", *p_updates = " << *p_updates << endl;

	//用两种方式表达地址
	cout << "Address: &updates = " << &updates;
	cout << ", p_updates = " << p_updates << endl;

	//利用指针改变变量的值
	*p_updates = *p_updates + 1;
	cout << "New updates = " << updates << endl;

	return 0;
}

二、声明和初始化指针

  • 指针声明必须指定指针指向的数据的类型。
  • 对每个指针变量名,都需要使用一个*
  • 可以在声明语句中初始化指针,在这种情况下,被初始化的是指针,而不是它指向的值。

        示例程序如下:
        int higgens = 5;
        int * pt = &higgens;       // 声明指针变量并初始化
        注意:一定要在对指针应用解除引用运算符(*)之前,将指针初始化为一个确定的、适当的地址。

三、使用 new 来分配内存

       将指针初始化为变量的地址,变量是在编译时从栈(stack)中分配的有名称的内存,而指针只是为可以通过名称直接访问的内存提供了一个别名。指针真正的用武之地在于,使用 new 运算符在运行阶段从被称为堆(heap)或自由存储区(free store)的内存区域中分配未命名的内存以存储值,在这种情况下,只能通过指针来访问内存。此时,指针指向的内存没有名称,我们可以说指针指向一个数据对象,它指的是为数据项分配的内存块。
        为一个数据对象(可以是结构,也可以是基本类型)获得并指定分配内存的通用格式如下:
        typeName * pointer_name = new typeName;
        需要在赋值运算符前后指定数据类型:用来指定需要什么样的内存和用来声明合适的指针。示例程序如下:

//use_new.cpp -- 使用new运算符,在程序运行阶段分配未命名的内存以存储值,格式:typename * pointer_name = new typename;
#include <iostream>
using namespace std;

int main()
{
	int nights = 1001;
	int * pt = new int;      //为存储int分配内存
	*pt = 1001;              //在分配的内存中存储值1001

	cout << "nights value = ";
	cout << nights << ": location " << &nights << endl;
	cout << "int ";
	cout << "value = " << *pt << ": location " << pt << endl;

	double * pd = new double;     //为存储double分配内存
	*pd = 10000001.0;         //在分配的内存中存储值10000001.0

	cout << "double ";
	cout << "value = " << *pd << ": location " << pd << endl;
	cout << "location of pointer pd: " << &pd << endl;

	cout << "size of pt = " << sizeof(pt);
	cout << ": size of *pt = " << sizeof(*pt) << endl;
	cout << "size of pd = " << sizeof(pd);
	cout << ": size of *pd = " << sizeof(*pd) << endl;

	return 0;
}

四、使用 delete 来释放内存

       当需要内存时,可以使用 new 来请求,如果通过 new 请求的内存在使用完后没有及时释放,将发生内存泄漏(memory leak),也就是说,被分配的内存再也无法使用了,如果内存泄漏严重,则程序将由于不断寻找更多内存而终止。所以,使用 new 运算符分配内存后,需要使用 delete 运算符释放内存,防止内存泄漏,用法如下:
        int * pt = new int;   // 分配内存
        .....                         // 使用内存
        delete pt;               // 释放内存
        这将释放指针指向的内存,但不会删除指针本身。
        不要尝试释放已经释放的内存块,只能用 delete 来释放使用 new 分配的内存,然而,对空指针使用 delete 是安全的。

五、使用 new 来创建动态数组

       在编译时给数组分配内存被称为静态联编(static binding),意味着数组是在编译时加入到程序中的。但使用 new 时,如果在运行阶段需要数组,则创建它;如果不需要,则不创建。还可以在程序运行时选择数组的长度。这被称为动态联编(dynamic binding),意味着数组是在程序运行时创建的,这种数组叫作动态数组(dynamic array)。使用静态联编时,必须在编写程序时指定数组的长度;使用动态联编时,程序将在运行时确定数组的长度。

1.创建动态数组

        在C++中要创建动态数组,只要将数组的元素类型和元素数目告诉 new 即可,必须在类型名后加上方括号,其中包含元素数目。创建动态数组的通用格式如下:
        type_name * pointer_name = new type_name [ num_elements ] ;
        使用 new 运算符可以确保内存块足以存储 num_elements 个类型为 type_name 的元素,而 pointer_name 将指向第一个元素。
        当程序使用完 new 分配的内存块时,应使用 delete 释放它们。然而,对于使用 new 创建的数组,应使用另外一种格式的 delete 来释放:
        delete [ ] pointer_name ;

2.使用动态数组

        可以以使用数组名的方式来使用 pointer_name,示例程序如下:

//arraynew.cpp -- 使用new运算符创建动态数组
#include <iostream>
using namespace std;

int main()
{
	double * p3 = new double[3];       //分配内存,存储三个double类型的元素
	p3[0] = 0.2;                       //将指针看作数组名,用数组表示法访问数组元素
	p3[1] = 0.5;
	p3[2] = 0.8;
	
	cout << "p3[1] is " << p3[1] << ".\n";

	p3 = p3 + 1;                       //将指针+1,这里显示指针和数组名的区别,数组名的值不能被修改,但指针是变量,可以修改值
	cout << "Now p3[0] is " << p3[0] << " and ";
	cout << "p3[1] is " << p3[1] << ".\n";

	p3 = p3 - 1;                       //指针指向原来的值,使程序可以给delete [] 提供正确的地址
	delete[] p3;                       //使用new [] 为数组分配内存,则应使用delete [] 来释放内存

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值