指针:
指针只是一个数字、变量、地址,它存储一个内存地址。仅仅如此
假设有一条街,街上只有一排房子(byte),这就是内存在电脑中的样子。每栋房子都有地址和门牌号,当我们需要送快递到某个房子或者上门取件(写入或者读取文件)时,我们得先知道他的地址。而指针就是用来告诉我们房子在哪–特定字节的地址在哪的。
而指针类型只是我们虚构出来的东西,好让我们轻松方便一点,这个类型只是在说,可能这个指针指向的数据是这个类型的,仅此而已。
获得变量的地址、修改他的值
int var = 8;
int* ptr = &var; //void*定义一个void类型指针,&var表示取var的存储地址
*ptr = 10; //将ptr指向的值改成10
我们可以通过VisualStudio的内存窗口搜索这个地址或者变量名来获得它的位置以及值:
这里若是改成void* ptr类型,结果照旧不变。但要注意类型不能小转大。
在堆中创建变量
int var = 8;
这种形式表示我们是在栈中为这个变量分配内存。
当我们需要在堆中创建变量时,就需要使用new关键字。创建后使用完需要释放内存。
char* buffer = new char[8]; //声明一个char类型的指针,并给他分配堆中的8字节空间
memset(buffer, 0, 8); //给buffer所在的内存位置为起点,填充一个8字节的大小为0的值
delete[] buffer; //释放这个char数组在内存中的值(未初始化的变量在内存中显示的是0xccccccc)
引申:new和delete到底是如何实现的?
new底层其实是call了malloc(memory allocation),从名字也可以知道它负责分配内存
delete则调用了free(),区别是new和delete不仅管理内存,还会调用constructor和destructor,另外它们都是operator,所以你可以重载它们,做一些有趣的事情。
指针的指针
延续上一节的例子,声明一个指向buffer指针所在地址的指针,这意味着我们需要通过两层指针去获取到值。
char** ptr = &buffer; //指向
0x00bcf7d8是buffer的地址,它存储的是buffer指向的值的地址
0xb8f10200就是buffer指向的值的地址,当我们根据这个地址去内存窗口查询时,得注意,这个地址是按照小端的方式存在内存中的。也就是我们每两位两位倒着输:0x0002f1b8