C的秘密(一)

1.指针与数组头等价又不等价

  • 等价在于数组名可以当作指针使用;

  • 不等价在于:

    int a[6] = {
          
          0, 1, 2, 3, 4, 5};
    int *p = a;
    int len_a = sizeof(a) / sizeof(int);
    int len_p = sizeof(p) / sizeof(int);
    printf("len_a = %d, len_p = %d\n", len_a, len_p);
    /*输出为:
    len_a = 6, len_p = 1
    */
    

    sizeof 就是根据符号的类型来计算长度的。对于数组 a,它的类型是int [6]。对于指针变量 p,它的类型是int *,两者类型不同。

2.用指针做函数返回的注意点

先看代码,猜猜输出什么:

  • int *func(){
          
          
        int n = 100;
        return &n;
    }
    int main(){
          
          
        int *p = func();
        printf("test value = %d\n", *p);
        printf("test value = %d\n", *p);
        return 0;
    }
    /*输出结果为:
    test value = 100
    test value = -2
    */
    

    由于返回的是函数内的局部定义变量,函数运行结束后会丢弃所有的局部数据。这里的丢弃不是说销毁抹掉数据,而是释放了局部数据所占用内存的使用权限,后面的代码可以使用这块内存,因此会被其他函数调用后覆盖这块内存。

3.虚拟地址与映射

​ 现代操作系统使用分页机制来管理内存,使得每个程序都有自己的地址空间,每当程序使用虚拟地址进行读写时,都必须转换为实际的物理地址。内存地址的转换是通过一种叫做页表(Page Table)的机制来完成的。

image-20201219124949299

​ 虚拟地址的作用:能够使得不同程序的地址空间相互隔离,提高内存使用效率。如果每个程序直接使用物理地址内存,那么程序之间所用的地址空间不是相互隔离的。恶意程序或bug程序易于改写其他程序的内存数据以致程序崩溃。

​ 提高虚拟地址,必须要说到一个硬件部件:MMU(Memory Management Unit),由它来负责将虚拟地址映射为物理地址。

image-20201220150554271

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/caq_jw/article/details/111701614