C++学习日记(15)—— 指针和自由存储空间

2021.3.24更新

因数据结构被迫回来复习指针了


来了来了,终于到了重头戏指针

这章我自己也学的很渣

一边写一边重新学习了


计算机在存储数据时必须跟踪的三种基本属性

  • 信息存储在何处
  • 存储的值为多少
  • 存储的信息是什么类型

指针是一个变量

它存储的是值的地址

而不是值本身

寻找常规变量的地址需要使用取地址运算符&

如果home是一个变量,则&home是它的地址

cout<<&home<<endl;

你会发现输出的是一个十六进制的值

因为这是常用于描述内存的表示法

使用常规变量的时候

值是指定的量

而地址是派生量

处理存储数据跟这个完全相反

将地址视为指定的量,而将值视为派生量

所以指针名表示的是地址

*运算符被称为间接值或解除引用运算符

用于指针就能得到这个地址存储的值

假设p是一个指针,p表示的是一个地址

那么*p就是存储在这个地址的值

*p和常规的int变量等效

总结一下

int test = 20;

int *p = &test;

在这里,test和*p是一样的

&test和p是一样的


声明和初始化指针

计算机需要跟踪指针指向的值的类型

例如,char的地址与double看上去没啥两样

但是char和double使用的字节数是不同的

他们存储时使用的内部格式也不同

因此指针声明必须指定指针指向的数据类型

例如int *p;

这里表明*p的类型是int

我们还可以说p是指向int的指针

p是地址,而*p是int而不是指针

传统上C程序员会这么写

int *p; 强调*p是一个int值

而C++程序员会这么写

int* p; 强调int*是一种类型——指向int的指针

但是在哪里空格其实都没问题

int* p1,p2;

这样做只创建了一个指针p1,而p2仍然是一个int变量

所以对于每个指针名,都需要一个*

指向不同类型的指针,占据的字节数是相同的

因为地址的长度或值既不能指示关于变量的长度或类型的任何信息

也不能指示该地址上有啥

一般来说,地址需要2个还是4个字节是由计算机系统决定的

可以像刚刚那样,在声明的时候初始化指针

int test = 20;

int *p = &test;


指针的危险

C++中创建指针的时候

计算机会分配用来存储地址的内存

但不会分配用来存储指针所指向的数据的内存

例如long *ha ;

*ha =233333

ha是个指针,但是它指向了哪里呢

不知道,因为没有地方存储233333的值


指针与数字

指针不是整型,显然计算机通常把地址当作整数来处理

但是指针描述的是位置,不能拿地址来做加减乘除

同样的,你不能随便把一个整数赋给指针

如果你要把一个十六进制的数作为地址赋给指针

那么你必须先通过强制类型转换把数字转化成指针相对应的类型


使用new来分配内存

在C语言中,我们可以使用malloc()库函数来分配内存

C++同样也可以使用这个方法,不过有了更好的方法——new运算符

程序员可以告诉new要为哪种数据类型分配内存

new将找到一个长度正确的内存块,并返回该内存块的地址

程序员的责任是将该地址赋给一个指针

int *p = new int;

new int告诉程序需要适合存储int的内存

new根据类型来确定需要多少字节的内存

然后找到这样的内存并返回其地址

最后把地址赋给p

int a;

int *s = &a;

与一般的方法相比new有什么优点呢

对于p和s来说两个都是被赋予了int变量的地址

但是我们是没有具体名称去称呼p所指的内存

也就是说p指向的内存并不是一个变量

这赋予了程序在管理内存上更大的控制权

通常为一个数据对象赋予内存的方法如下

typeName * pointer_name =  new typeName;

new通常从被称为堆或者自由存储区的内存区域分配内存

像上面的一般方法则是从栈来分配内存


使用delete来释放内存

使用new请求内存,使用过后我们需要把这部分内存归还回去

这就是delete的作用

使用delete的时候后面要加上指向内存块的指针

int *p = new int;

delete p;

这会释放p所占的内存但不会删除p本身

可以重新对p分配内存

new和delete一定要配对使用,否则会发生内存泄漏

被分配的内存不能再使用了

也不能重复的释放一个指针的内存

int *p = new int;

delete p;

delete p;

不能使用delete来释放声明变量所获得的内存

int a;

int *s = &a;

delete s;


 

发表评论

您的电子邮箱地址不会被公开。