• 内存四区


    1.代码区:
    代码区Code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的。

    2. 静态区

    所有的全局变量以及程序中的静态变量都存储在静态区。

    #include<stdio>
    int c = 0;//静态区
    void test(int a,int b)
    {
            printf(“%d %d
    ”,&a,&b); //在栈区
    }
    int main()
    {
         static int d = 0;
         int a = 0; //栈区
         int b = 0;
      printf(“%d %d %d %d %d
    ”,&a,&b,&c,main,d);
          return 0;
    }

    3.堆区

    对于一个32位操作系统,最大管理4G内存,其中1G是给操作系统自己用的,剩下的3G都是给用户程序,一个用户程序理论上可以使用3G空间

    int *p = (int*)malloc(sizeof(int) * 10); //在堆中申请内存,在堆中申请了一个10个int型大小内存。
    char *p1 = mallocsizeof(char) * 10); //在队中申请10个char这么大的空间
    
    free(p);//释放通过malloc分配的堆内存
    free(p1); //释放通过maclloc分配的对内存

    4.栈区

    栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出。

    对于自动变量,什么时候入栈,什么时候出栈,是不需要程序控制的,由C语言编译器实现的。

    #include<stdio.h>
    int *geta() //函数的返回值是个指针
    {
            auto int a = 100;
            return &a;
    }//int a的作用域就是{}
    int main()
    {
            int *p = geta();//这里得到的是一个临时变量的地址,这个地址在函数geta调用结束以后已经无效了
            *p = 100;
            printf(“%d
    ”,*p);
            return 0;
    }

           栈不会很大,一般都是K为单位

           栈溢出:当栈空间已满,但还往栈内存压变量,这个就叫栈溢出。

    int *geta() //错误,不能将一个栈变量的地址通过函数的返回值返回
    {
        int a = 0;
        return &a;
    }
    
    int *geta1() //通过函数的返回值可以返回一个对地址,但记得一定要free
    {
        int *p = malloc(sizeof(int));
        return p;
    }
    int main()
    {
        int *getp = geta1();
        *getp = 100;
        free(getp);
    }
    int *geta2() //合法
    {
        static int a = 100;
        return &a;
    }
    int main()
    {
        int *getp = geta2();
        *getp = 100;
        //free(getp);
    }
    int main() //结果正常。
    {
        int *p = NULL;
        p = malloc(sizeof(int) * 10);
        p[0] = 1;
        p[1] = 2;
        printf(“p[0] = %d, p[1] = %d
    ”,p[0],p[1]); //
        free(p);
    }
    //结果崩溃
    void getheap(int *p)
    {
        p = malloc(sizeof(int) * 10);
    }
    int main()
    {
        int *p = NULL;
        getheap(p);
        p[0] = 1;
        p[1] = 2;
        printf(“p[0] = %d, p[1] = %d
    ”,p[0],p[1]); //
        free(p);
    }

    分析:主函数的p的值NULL ,传递给函数getheap中的*p,在函数中malloc分配的内存分配给了函数中的*p,分配的malloc是堆中的,mian中的内存都在栈中的,意味这main函数中的p没有得到内存地址。

    修正:

    void getheap(int **p)
    {
        *p = (int*)malloc(sizeof(int) * 10);
    }
    int main()
    {
        int *p = NULL;
        getheap(&p);
        p[0] = 1;
        p[1] = 2;
        printf(“p[0] = %d, p[1] = %d
    ”,p[0],p[1]); //
        free(p);
    }

    这样就可以给指针p分配内存了。

  • 相关阅读:
    hashlib对密码进行加密
    django中model的choices字段
    django在表发生变化后需执行命令
    djangopost请求报错:Forbidden (CSRF token missing or incorrect.)
    阻止浏览器自动填入账号和密码
    django表的models的参数及含义
    django设置静态文件
    Django的admin管理工具设置中文
    径向渐变
    文档对象的获取
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11074687.html
Copyright © 2020-2023  润新知