• C语言内存分布



    内存四区图示

    代码区

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

    静态区

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

    栈区

      栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出。对于自动变量,什么时候入栈,什么时候出栈,是不需要程序控制的,由C语言编译器。实现栈不会很大,一般都是以K为单位的。

      当栈空间以满,但还往栈内存压变量,这个就叫栈。溢出对于一个32位操作系统,最大管理管理4G内存,其中1G是给操作系统自己用的,剩下的3G都是给用户程序,一个用户程序理论上可以使用3G的内存空间。

    注意:C语言中函数参数入栈的顺序是从右往左。

    堆区

      堆heap和栈一样,也是一种在程序运行过程中可以随时修改的内存区域,但没有栈那样先进后出的顺序。堆是一个大容器,它的容量要远远大于栈,但是在C语言中,堆内存空间的申请和释放需要手动通过代码来完成。

    代码示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #include <stdio.h>

    int c = 0; // 静态区

    void test(int a, int b) // 形参a,b都在栈区
    {
    printf("%d, %d ", &a, &b);
    }

    int *geta() // 函数的返回值是一个指针
    {
    int a = 100; // 栈区
    return &a;
    } // int a的作用域就是这个{}

    int main()
    {
    int *p = geta(); // 这里得到一个临时栈变量的地址,这个地址在函数geta调用完成之后已经无效了
    *p = 100;
    printf("%d ", *p);
    static int d = 0; // 静态区
    int a = 0; // 栈区
    int b = 0;

    printf("%d, %d, %d, %d, %d ", &a, &b, &c, &d, main);
    test(a, b);
    return 0;
    }

    /*
    输出结果
    100
    2619740, 2619728, 9404720, 9404724, 9376059
    2619512, 2619516
    */

    堆使用注意事项

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #include <stdio.h>
    #include <stdlib.h>

    int *geta() // 错误,不能将一个栈变量的地址通过函数的返回值返回
    {
    int a = 0;
    return &a;
    }

    int *geta1() // 可以通过函数的返回值返回一个堆地址,但记得,一定要free
    {
    int *p = (int *)malloc(sizeof(int)); // 申请了一个堆空间
    return p;
    }

    int *geta2() // 合法的,但是记住这里不能用free
    {
    static int a = 0; // 变量在静态区,程序运行过程中一直存在
    return &a;
    }

    void getHeap(int *p)
    {
    printf("p = %p ", &p);
    p = (int *)malloc(sizeof(int) * 10);
    } // getHeap执行完之后,p就消失了,导致他指向的具体堆空间的地址编号也随之消失了
    // 这里发生了内存泄漏

    void getHeap1(int **p)
    {
    *p = (int *)malloc(sizeof(int) * 10);
    } // 这里的操作就是正确的

    int main()
    {
    int *p = NULL;
    printf("p = %p ", &p);
    getHeap(p); // 实参没有任何改变
    getHeap1(&p); // 得到了堆内存的地址
  • 相关阅读:
    Educational Codeforces Round 67 D. Subarray Sorting
    2019 Multi-University Training Contest 5
    Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code
    Educational Codeforces Round 69 D. Yet Another Subarray Problem
    2019牛客暑期多校训练第六场
    Educational Codeforces Round 68 E. Count The Rectangles
    2019牛客多校第五场题解
    2019 Multi-University Training Contest 3
    2019 Multi-University Training Contest 2
    [模板] 三维偏序
  • 原文地址:https://www.cnblogs.com/piterzhang/p/9010944.html
Copyright © 2020-2023  润新知