zoukankan      html  css  js  c++  java
  • 内存四区

    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分配内存了。

  • 相关阅读:
    我的浏览器收藏夹分类
    我的浏览器收藏夹分类
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 315 计算右侧小于当前元素的个数
    Java实现 LeetCode 315 计算右侧小于当前元素的个数
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11074687.html
Copyright © 2011-2022 走看看