Linux_C程序内存分布

前言

在学习Linux下C编程时, 我们了解到程序中的每一个变量都是在内存中有分布的.
程序占用的内存区域如下: 系统空间、命令行参数区、栈区、堆区、数据段、文本段.

linux下进程的内存布局

在这里插入图片描述
一般来说栈区的生长方向是从上往下的, 堆区的生长方向是从下往上.
但是对于不同的系统栈区的生长方向会有不一样的变化, 接下来我们一起验证

程序验证内存布局

程序源码

/*********************************************************************************
 *      Copyright:  (C) 2021 guanyunpeng
 *                  All rights reserved.
 *
 *       Filename:  memory_layout.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2021年08月16日)
 *         Author:  guanyunpeng <364521112@qq.com>
 *      ChangeLog:  1, Release initial version on "2021年07月30日 22时44分35秒"
 *                 
 ********************************************************************************/


#include <stdio.h>
#include <stdlib.h>

int g_val1;
int g_val2;

int g_val3 = 1;
int g_val4 = 2;

void local_variables(void)
{
    int local_variables1;
    int local_variables2;

    printf("(栈区)local_variables1  的地址为: %p\n", &local_variables1);
    printf("(栈区)local_variables2  的地址为: %p\n", &local_variables2);

}

int main (int argc, char **argv)
{
    char    *ptr1 = malloc(10);
    char    *ptr2 = malloc(10);

    static int sta_val1 = 5;
    static int sta_val2 = 6;

    char    *str1 = "hello";
    char    *str2 = "world"; 

    local_variables();

    printf("(堆区)ptr1              的地址为: %p\n", &ptr1);
    printf("(堆区)ptr2              的地址为: %p\n", &ptr2);
    printf("(.bss)g_val1            的地址为: %p\n", &g_val1);
    printf("(.bss)g_val2            的地址为: %p\n", &g_val2);
    printf("(.data)sta_val1         的地址为: %p\n", &sta_val1);
    printf("(.data)sta_val2         的地址为: %p\n", &sta_val2);
    printf("(.data)g_val3           的地址为: %p\n", &g_val3);
    printf("(.data)g_val4           的地址为: %p\n", &g_val4);
    printf("(.rodata)\"hello\"        的地址为: %p\n", str1);
    printf("(.rodata)\"world\"        的地址为: %p\n", str2);


    return 0;
} 

运行结果

测试一

Linux系统版本信息如下:
在这里插入图片描述
运行结果:
在这里插入图片描述
我们可以清楚的看到各个变量的存储位置
这里可能有人要有疑问了, 比如俩个字符串的存放地址为什么是"hello"要比"world"低呢?
首先我们先定义的char *str1 = “hello”; 再定义的char *str2 = “world”; 所以在地址分布上是先存放的"hello", 再存放"world". 其他变量也是如此.
这里特别注意一下, 看栈区的变量
local_variables1是先定义的, 地址为: 0x7ed5042c
local_variables2是后定义的, 地址为: 0x7ed50428
由此可见, 此Linux系统下, 栈空间的生长方向是从上往下的.

测试二

Linux系统版本信息如下:
在这里插入图片描述
运行结果:
在这里插入图片描述

我们可以清楚的看到各个变量的存储位置
这里特别注意一下, 看栈区的变量
local_variables1是先定义的, 地址为: 0x7fffb2a75290
local_variables2是后定义的, 地址为: 0x7fffb2a75294
由此可见, 此Linux系统下, 栈空间的生长方向是从下往上的.

补充一个有关静态局部变量的问题

我们都知道静态局部变量存储在.data段的, 那么此时我们如果重复调用某个函数, 这个函数里面有一个静态局部变量, 程序是会每次调用的时候都给这个静态局部变量分配内存吗?还是只分配一次呢? 接下来我们通过程序来验证!

验证程序源码


#include <stdio.h>

int test ()
{
    static int a;

    a++;
    printf("a,p:%p\n", &a);
    printf("a:%d\n", a);
    return 0;
} 


int main (int argc, char **argv)
{
    int     i = 0;

    for(i=0; i<3; i++)
    {
        printf("第%d次\n", i);
        test();
    }

    return 0;
} 

运行结果如下

在这里插入图片描述
我们通过运行结果可以看到, 多次调用函数, 并不会为函数中的静态局部变量多次分配内存.
这是因为静态局部变量只在定义它的函数内有效, 只是程序仅分配一次内存, 函数返回后, 该变量不会消失; 静态局部变量的生存期虽然为整个工程, 但是其作用仍与局部变量相同, 即只能在定义该变量的函数内使用该变量.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值