堆&栈&进程内存空间分配方式&static

  1. 大小
    Linux: 10M = 10240KB

    windows: 1M = 1024KB

  2. 可以静态分配(在编译阶段就能确定大小,由编译器进行分配);

    也可以动态分配(使用alloca()函数可以动态分配栈的内存空间,释放的时候由编译器自己释放,不需要手动释放)

堆(链表维护,内存不连续)

  1. 不能静态分配,只能动态分配(堆的申请是在执行过程中执行的)

    堆是使用malloc()、calloc()、realloc()等函数动态分配的

  2. 在堆上频繁的调用new/delete容易产生内存碎片

进程的内存空间分配方式

进程的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数据都是互不干扰。

  1. 代码区(只读)(低地址)

    • 程序代码
    • 数字常量
  2. 静态数据区(中地址)

    • 字符串常量(只读数据段,挨着数据段)

    • 全局变量(已经初始化)

    • 静态变量(static修饰)

      c语言中static的语义
      1.static变量:
      1).局部
      只初始化一次,静态局部变量存放在内存的全局数据区。函数结束时,静态局部变量不会消失,每次该函数调用时,也不会为其重新分配空间。它始终驻留在全局数据区,直到程序运行结束。
      ​ 2).全局
      2.static函数(也叫内部函数)只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。

  3. 动态数据区(高地址)

    • :链式结构(向高地址方向增长)
    • :线性结构(函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。)(向低地址方向增长)
    • 本地变量
    • 程序通过堆栈的基地址和偏移量来访问本地变量。
      在这里插入图片描述
      下图来源:Unix环境高级编程一书中7.6小节
      在这里插入图片描述

用nm命令查看全局变量在bss段,data段

//test.c
#include <stdio.h>

int global_variable;
int initialized_global_variables = 1;

int add(int a, int b){
	return a + b;
}

int main(){

	int a = 1;
	printf("hello %d\n", add(a, 1));
	
	return 0;
}

局部变量a在栈中,栈和堆在程序运行时才有,所以可执行文件看不到a

[root@izbp1bvlfc3omk6i0e7ht2z C]# nm test.out
/*********************************
000000000040052d T add//静态绑定函数地址
*********************************/
0000000000601038 B __bss_start
0000000000601038 b completed.6355
0000000000601030 D __data_start
0000000000601030 W data_start
0000000000400470 t deregister_tm_clones
00000000004004e0 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000400608 R __dso_handle
0000000000600e28 d _DYNAMIC
0000000000601038 D _edata
0000000000601040 B _end
00000000004005f4 T _fini
0000000000400500 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
0000000000400768 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
/********************************************
000000000060103c B global_variable//未初始化在bss段
********************************************/
                 w __gmon_start__
000000000040061c r __GNU_EH_FRAME_HDR
00000000004003e0 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
/********************************************
0000000000601034 D initialized_global_variables//初始化在data段
********************************************/
0000000000400600 R _IO_stdin_used
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
00000000004005f0 T __libc_csu_fini
0000000000400580 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000400541 T main
/********************************************
                 U printf@@GLIBC_2.2.5//printf需要运行时动态链接,此时不绑定函数地址
********************************************/               
00000000004004a0 t register_tm_clones
0000000000400440 T _start
0000000000601038 D __TMC_END__

在这里插入图片描述

static用法和作用

  1. 声明静态变量

    • 全局变量:静态全局变量仅对当前文件可见,其他文件不可访问,避免不同文件变量同名的冲突,降低耦合性。

    • 局部变量:存储于进程的全局数据区,编译器自动对其初始化,函数结束,内存空间也不会回收,作用域在函数体内,有利于程序模块化。

  2. 声明函数

    • 静态函数只能在声明它的文件中可见,其他文件不能引用该函数
    • 不同的文件可以使用相同名字的静态函数,互不影响
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值