变量存储重温与Clion编辑器的学习与实践

一、C程序中全局/局部变量、堆、栈变量分配

1、存储分配方式

从静态存储区域分配: 内存在程序编译时已经分配好,在程序的整个运行期间都存在。例如全局变量,静态变量。
在栈上创建 : 在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。效率很高,但分配的内存容量有限。
从堆上分配: 动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定,使用灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,频繁地分配和释放不同大小的堆空间将会产生堆内碎块。

2、内存分配

C语言程序占用的内存分成了五个部分内容:
栈区:stack, 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等,内存的分配是连续的,即所分配的内存是在一块连续的内存区域内.当我们声明变量时,编译器会自动接着当前栈区的结尾来分配内存。
堆区: 一般由程序员分配释放, 若程序员不释放,程序结束时可能由操作系统回收。类似于链表,在内存中的分布不是连续的,它们是不同区域的内存块通过指针链接起来的。一旦某一节点从链中断开,我们要人为的把所断开的节点从内存中释放。
全局区:static,也称静态区。全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在同一块区域, 未初始化的全局变量和静态变量在相邻的另一块区域。 程序结束后由系统释放
文字常量区:放置常量字符串, 程序结束后由系统释放。
程序代码区:存放函数体的二进制代码。

3、内存属性

静态分配内存:是在程序编译和链接时就确定好的内存。
动态分配内存:是在程序加载、调入、执行的时候分配/回收的内存。

*Text & Data & Bss

  • text: 也称为代码段(Code),用来存放程序执行代码,同时也可能会包含一些常量(如一些字符串常量等)。该段内存为静态分配,只读(某些架构可能允许修改)。
    这块内存是共享的,当有多个相同进程(Process)存在时,共用同一个text段。

  • data: 也有的地方叫GVAR(global value),用来存放程序中已经初始化的非零全局变量。静态分配。

  • data又可分为读写(RW)区域和只读(RO)区域。
    -> RO段保存常量所以也被称为.constdata
    -> RW段则是普通非常全局变量,静态变量就在其中

  • bss: 存放程序中为初始化的和零值全局变量。静态分配,在程序开始时通常会被清零。
    text和data段都在可执行文件中,由系统从可执行文件中加载;而bss段不在可执行文件中,由系统初始化。
    这三段内存就组成了我们编写的程序的本体,但是一个程序运行起来,还需要更多的数据和数据间的交互,否则这个程序就是死的,无用的。所以我们还需要为更多的数据和数据交互提供一块内存——堆栈。

堆栈(Heap& Stack)
堆和栈都是动态分配内存,两者空间大小都是可变的。

  • Stack: 栈,存放Automatic Variables,按内存地址由高到低方向生长,其最大大小由编译时确定,速度快,但自由性差,最大空间不大。

  • Heap: 堆,自由申请的空间,按内存地址由低到高方向生长,其大小由系统内存/虚拟内存上限决定,速度较慢,但自由性大,可用空间大。
    每个线程都会有自己的栈,但是堆空间是共用的。

3、图解

在这里插入图片描述

  • text、data(gvar)、bss 在内存中地址较低低的位置(low level address),而堆栈则在相对较搞的位置。
  • 堆(Heap)往高地址方向生长,栈(Stack)往低地址方向生长。

二、在Ubuntu(x86)系统和STM32(Keil)中分别进行编程、验证

进行验证的程序代码

#include <stdio.h>
#include <stdlib.h>
//定义全局变量
int init_global_a = 5;
int uninit_global_a;
static int inits_global_b = 6;
static int uninits_global_b;
void output(int a)
{
   
	printf("anaconda");
	printf("%d",a);
	printf("\n");
}

int main( )
{
      
	//定义局部变量
	int a=6;
	static int inits_local_c=6, uninits_local_c;
    int init_local_d = 1;
    output(a);
    char *p;
    char str[10] = "ghz";
    //定义常量字符串
    char *var1 = "1234567890";
    char *var2 = "abcdefghij";
    //动态分配
    int *p1=malloc(4);
    int *p2=malloc(4);
    //释放
    free(p1);
    free(p2);
    printf("栈区-变量地址\n"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值