【编程语言】C/C++指针笔记(1)

内存与地址

计算机里,数据存放在内存单元里,一般把一个字节成为一个内存单元,为了更方便访问内存单元,就把这些内存单元进行地址编号,根据地址编号,可准确找到其对应内存单元,可以说一个地址编号对应一个内存单元。c语言每个变量都对应一块内存空间,而内存中每个地址单元均是有地址编号的。c语言中把地址形象地称作指针,在c语言里,可以用&符号来求某个变量的地址。
如下是一个最简单的实例,其输出结果打印了他们的值以及其地址

    #include <stdio.h>
    int main(void)
    {
        char c='A';
        int a=100;
        printf("a=%d\n",a);//输出变量a的值
        printf("&a=%x\n",&a);//输出变量a的地址
        printf("c=%c\n",c);
        printf("&c=%x\n",&c);
        return 0;
    }

指针变量定义为:类型 * 变量名;
举个最简单的例子就是int *p;
也可以定义两个int pa,pb;

指针变量的引用

访问内存空间,一般分为直接访问和间接访问。如果我们知道内存空间的名字,我们就可以直接访问。由于变量也代表有名字的内存单元,所以通过变量名操作变量也就是相当于通过内存单元名字直接访问变量对应的内存单元。如果我们知道内存空间的地址,也可以直接通过该地址间接访问该空间。对内存空间的访问操作一般是指存或取的操作。我们可以通过间接访问符*来访问指针指向的空间

int *p,a=3;//p中保存变量a对应内存单元的地址
p=&a

在该地址 p 前面加上间接访问符 *,即代表该地址对应的内存单元。而变量 a 也对应该内存单元,故 *p 就相当于 a。

    printf("a=%d\n",a); //通过名字,直接访问变量a空间(读取)
    printf("a=%d\n",*p); //通过地址,间接访问变量a空间(读取)
    *p=6;//等价于a=6;间接访问a对应空间(内存)

野指针

“野”指针随机指向一块空间,该空间中存储的可能是其他程序的数据甚至是系统数据,故不能对“野”指针所指向的空间进行存取操作,否则轻者会引起程序崩溃,严重的可能导致整个系统崩溃。
例如:

    int *pi,a; //pi未初始化,无合法指向,为“野”指针
    *pi=3; //运行时错误!不能对”野”指针指向的空间做存入操作。该语句试图把 3 存入“野”指针pi所指的随机空间中,会产生运行时错误。
    a=*pi; //运行时错误!不能对”野”指针指向的空间取操作。该语句试图从“野”指针pi所指的空间中取出数据,然后赋给变量a同样会产生运行时错误。

正确的食用方法

    pi=&a;//让pi有合法的指向,pi指向a变量对应的空间
    *pi=3;//把3间接存入pi所指向的变量a对应的空间

放csdn一位大佬写的程序以及解释

int main()
{
     int *a=new int[6];
     a[2]=99;
     int *b =a;
     cout<<a[2]<<endl;
     cout<<b[2]<<endl;
     delete []a;             //释放了a指向的空间
     cout<<b[2]<<endl; //此时b指向的内存已经释放了,b仍然使用,b指向未知区域
     return 0;
}

输出:

99
99
0x22fe48
0x22fe40   //此时b的地址不是原来的地址了,而是未知的,看到反而是在低位地址
3932504

当程序运行时是作为一个进程,而一个进程就有自己的一个虚拟空间,低地址是代码和数据,然后是运行时堆,然后再是共享库,然后是栈空间。用于函数局部调用时
此时b指向了低位的进程地址,此时操作野指针b读取可能不报错,但是一旦写数据,程序就奔溃了
在没有保护措施的情况下随意修改进程地址数据是很危险的,一般高位的OS内核地址都是进行保护的。

posted @ 2020-07-25 20:48  Boky_Learn  阅读(134)  评论(0)    收藏  举报