进程内存分布 与 类型限定符

本文详细解析了进程内存的五个区域:代码段、全局数据段、静态数据段、堆和栈,以及C语言中不同类型的变量在这些区域的存储情况。通过实例展示了如何使用const、static和volatile关键字影响变量的存储和行为。强调了栈和堆的使用优缺点,并提供了内存管理的实践示例。
摘要由CSDN通过智能技术生成

进程内存分布

  • text 代码段:

    ​ 存储的是二进制指令、常量(字符串字面值),该内存段的权限为只读,一旦强行修改就会产生段错误。

  • data 全局数据段:

    ​ 里面存储着初始化过的全局变量、静态变量。

  • bss 静态数据段:

    ​ 里面存储着末初始化过的全局变量、静态变量,该内存段在程序执行前会被初始化为0。

  • heap 堆:

    ​ 由于程序员手动管理,该内存无法与标识符建立映射关系(无法取名字),必须与指针配合使用。

    • 优点:够大,分配和释放可控。
    • 缺点:使用麻烦,容易产生内存泄漏、内存碎片。
  • stack 栈:

    ​ 由系统自动管理,随着函数被调用,会自动分配内存,函数执行结束后自动释放内存。

    • 优点:使用方便,采用栈结构方式管理安全,不会产生内存泄漏、内存碎片。
    • 缺点:大小有限,一次使用过多可能会产生段错误,分配和释放不可控不适合长期保存数据。

示例 ps:stack作用见后页

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

int data_glocal = 2333;						//初始化的全局变量,存储于data中;
int bss_glocal;								//未初始化的全局变量,存储于bss中,默认会被初始化为0;

static void func(void);						//用于限制函数func的作用范围:只在本文件中使用。
											//可防止函数、全局变量重名、防止被人调用。

void main(void)
{
    static int data_local = 2333;			//初始化的静态局部变量,存储于data中;
    static int bss_local;					//未初始化的静态局部变量,存储于bss中,默认会被初始化为0;
    int stack_local_0 = 2333;				//初始化的局部变量,储存于stack中
    int stack_local_1;						//未初始化的局部变量,储存于stack中,数值随机。
	int n = 9;								//随便设定一个值 
 	int *heap_arr_n = malloc(sizeof(int)*n);//向系统申请n个int字节的内存空间,存放于heap中。
    printf("----全局变量-----\n"); 
		printf("定义数值:		data_glocal = %d\n",data_glocal);
    	printf("未定义数值:		bss_g1ocal = %d\n",bss_glocal);
    printf("----局部变量-----\n"); 
    	printf("定义数值的静态:	data_local = %d\n",data_local);
    	printf("未定义数值的静态:	bss_local = %d\n",bss_local);
    	printf("定义数值的变量:	stack_local_0 = %d\n",stack_local_0);
    	printf("未定义数值的变量:	stack_local_1 = %d\n",stack_local_1);
}

类型限定符

  • auto

    ​ 用于定义自动申请、自动释放的变量(局部变量),不加代表了加。

    • 不能用于修饰全局变量
  • const (常数)

    ​ 显示地"保护"变量不被修改
    ​ 但是,如果要强制修改还是可以修改的(通过指针,对变量修改)
    ​ 如果对初始化过的全局变量,用const修饰后,存储位置从data变成了text

  • extern (外部的)
    声明外部的全局变量,声明的变量已在别处定义过,请放心使用
    但是只能临时通过编译,如果没有定义,链接时依然会报错
    只是声明变量,不能赋值

  • static (静态的)
    被static修饰过的变量称为静态局部变量,局部全局变量
    改变存储位置:
    改变局部变量的存储位置,由stack改data或者bss(由是否初始化决定)
    延长生命周期:
    延长局部变量的生命周期
    限制作用范围:
    限制全局变量、函数只能在本文件内使用
    可以防止函数、全局变量重名、防止被别人调用

  • register (寄存器)
    申请把变量的存储介质由内存转移到寄存器存储,如果能成功,数据的读取速度会大幅提升,寄存器数量有限,申请可能失败

    • 存储介质:
      硬盘->内存->高速缓存->寄存器->CPU
  • volatile (不稳定的)

  • 编译器每次读取 volatile 定义的变量时,都从内存地址处重新取值。
    编译器的取值优化:
    变量的值没有发生改变时,后续的取值会进行优化,不再去内存中读取,而是使用第一次读取的结果,可以节约时间

示例


#include <stdio.h>

/******************
extern Ex_global;	//声明外部的全局变量,声明的变量已在别处文件定义过,避免报错。
*****************/

/**************************************************
测试const功能函数
**************************************************/
const int Num_text = 0;	//如果对初始化过的全局变量,用const修饰后,存储位置从data变成了text
int *Num_text_p = &Num_text;	//声明对象为num_text的指针,对num_text进行测试
void func_const(void)
{
    const int num_0 = 0;
	int* num_0_p = &num_0;		//声明对象为const num_0的指针,测试可否改变其值;
	
    int num = 0;
	const int *num_p1 = &num;	//声明对象为num的指针。const保护其值不能改变
	int* const num_p2 = &num;	//声明对象为num的指针。const保护其指向地址不能改变
    const int* const num_p3 = &num;	//声明对象为num的指针。const保护其值与指向地址不能改变。
    /***********编辑想改变的变量或者指针,进行测试。**********/
    							/**示例**/
	printf("num_0 = %d\n",num_0);
//	num_0++;		//不能修改
	(*num_0_p)++;	//可以修改num_0的值
	printf("num_0 = %d\n",num_0);

	printf("num_text = %d\n",Num_text);
//	Num_text++;
	(*Num_text_p)++;	//出现段错误:修改只读空间text的值
	printf("num_text = %d\n",Num_text);
}

/**********************************
测试static功能函数
**********************************/
void func_static(void)
{
    for(int i=1;i<=10;i++)
    {
		static int f=1;
		f=f*2;
        printf("%d\n",f);
    }
}

/********************************
测试volatile
********************************/
void func_volatile(void)
{
    volatile int i=10;
    int arr_i[1000] = {};
    for(int j = 0;j<1000;j++)
    {
        arr_i[j] = i;
        printf("arr_i[%d] = %d\n",j,arr_i[j]);
    }
}

void main(void)
{
	func_volatile();
	func_static();
	func_const();
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@小倔牛@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值