【C语言】---内存四区(二)


一、程序的内存四区模型

在这里插入图片描述
流程说明
1、操作系统把物理硬盘代码load到内存
2、操作系统把c代码分成四个区
在这里插入图片描述

3、操作系统找到main函数入口执行

1.栈区和堆区

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *get_str()
{
        char str[] = "abcdedsgads"; //栈区,
        printf("str = %s\n", str);

        return str;
}

char *get_str2()
{
        char *tmp = (char *)malloc(100);
        if (tmp == NULL)
        {
                return NULL;
        }

        strcpy(tmp, "adsagldsjglk");

        return tmp;
//注意 return不是把内存块 64个字节,给return出来
//而是把内存块的首地址(比如内存的编号0xaa11) ,返回给 p
// 理解指针的关键是内存,没有内存哪里来的指针

}

int main(void)
{
        char buf[128] = { 0 };

//      strcpy(buf, get_str()); //此处可能是拷贝完在释放(结果是str的值)
//      printf("buf = %s\n", buf); //乱码,不确定
// 		char *p1 = NULL;
//		p1 = get_str();
//		printf("p1 = %s\n",p);   //此时一定不对
        char *p = NULL;
        p = get_str2();
        if (p != NULL)
        {
                printf("p = %s\n", p);

                free(p);    //解除p与地址的指向关系
                p = NULL;

                if (p != NULL)
                {
                        free(p);
                }

        }

p = adsagldsjglk

栈区:
在这里插入图片描述

堆区:
在这里插入图片描述

2.全局区

#include <stdio.h>

char *get_str1()
{
        char *p = "abcdef1"; //文字常量区

        return p;
}

char *get_str2()
{
        char *q = "abcdef2"; //文字常量区

        return q;
}

int main(void)
{
        char *p = NULL;
        char *q = NULL;

        p = get_str1();
        //%s: 指针指向内存区域的内容
        //%p: 打印p本身的值
        printf("p = %s, p = %p\n", p, p);

        q = get_str2();
        printf("q = %s, q = %p\n", q, q);

        printf("\n");
        return 0;
}
~
p = abcdef1, p = 0x55d52b31d004
q = abcdef2, q = 0x55d52b31d00c

内存四区图:
在这里插入图片描述

二、函数的调用模型

在这里插入图片描述

三、函数调用变量传递分析

在这里插入图片描述

  1. main函数中可以在栈/堆/全局分配内存,都可以被func1和func2使用
  2. func2在栈上分配的内存,不能被func1和main函数使用
  3. func2中malloc的内存(堆),可以被main和func1函数使用
  4. func2中全局分配“abcdefg”(常量全局区)内存,可以被func1和main函数使用

四、栈的生长方向和内存存放方向

在这里插入图片描述
栈的生长方向
栈的生长方向:先后入栈二个变量a,b。如果b的内存地址确实比a小,说明栈的生长方向是由上往下的,即从高地址到低地址。
数组的生长方向:不管数组在栈区还是堆区,数组的生长方向都是从下往上的。也就是从低地址到高地址的。
比如数组: char buf[100]; buf[1]的内存地址肯定大于buf[0]的内存地址

#include <stdio.h>

int main(void)
{
        int a;
        int b;

        printf("&a = %p, &b = %p\n", &a, &b);


        int buf[100];
        printf("buf: %p, buf+1:%p\n", buf, buf+1);


        printf("\n");
        return 0;
}
~        
&a = 0x7ffc8ca55ac8, &b = 0x7ffc8ca55acc
buf: 0x7ffc8ca55ad0, buf+1:0x7ffc8ca55ad4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值