C语言中数据放在哪里

1.未初始化的全局变量(.bss段)

.bss段用来存放那些没有初始化和初始化为0的全局变量
int bss_array[1024*1024]
int main(int argc,char*argv[])
{
    return 0;
}
变量bss_array的大小为4MB,可执行文件的大小只有5KB,由此可见bss类型全局变量只占运行时的内存空间,而不占用文件空间
现代大多数错做系统在加载程序的时候,会把所有的bss全局变量清0。但为了保证程序的可移植性,手动把这些变量初始化为0
也是一个好习惯,这样一来这些变量都有个确定的初始值,当然作为全局变量,在整个程序的运行周期内,bss数据是一直存在的


2.初始化过的全局变量(.data段)

.data段用来存放那些初始化为非零的全局变量
int bss_array[1024*1024]={1};
int main(int argc,char*argv[])
{
    return 0;
}
上述程序仅仅是把初始化的值改为非零,文件就变为了4MB多,由此可见,data类型的全局变量既占文件空间
又占用运行时的内存空间,同样作为全局变量,在整个运行周期内,data数据是移植存在的

3.常量数据(.rodata)

.rodata段的,ro代表read only ,.rodata段就是用来存放常量数据的,rodata类型的数据注意以下几点:
(1)常量不一定就那个在rodata里,有的立即数直接和指令编码在一起,存放在代码段(.text)
(2)对于字符常量,编译器会自动去除重复的字符串,保证一个字符串在一个可执行文件(EXE/SO)中只存在一份赋值
(3)rodata在多个进程间是共享的,这样可以提高运行空间的利用率
(4)在有的嵌入式系统里面,radata放在ROM里面,(或者NOR Flash)里,运行时直接读取,无须加载到RAM内存中
(5)在嵌入式LINUX系统中,也可以通过一种叫作XIP(就地执行)的技术,直接读取而无须加载到RAM内存中
(6)常量是不能修改的,修改常量在Linux下会出现段错误

4.代码(.text段)

.text段用于存放代码(如函数)和部分整数常量,它与.rodata段很相似,主要不同在于这个段是可以执行的

5.栈 stack

栈用于存放临时变量和函数参数。栈作为一种基本的数据结构,可以用来实现函数的调用,尽管大多数编译器在优化时,会把常用的参数或者局部变量放入寄存器中,但用栈来管理函数调用时的临时变量(局部变量和参数)是通用做法,前者只是辅助手段,且在函数中使用,一旦调用下一层函数,这些值仍然要存入栈中才行。
       通常情况下,栈向下(低地址)增长,每向栈中PUSH一个元素,栈顶就向低地址扩展,每从栈中POP一个元素,栈顶就向高地址回退。存放在栈中的数据只在当前函数和一下层函数中有效,一旦函数返回,这些数据也被自动释放,继续访问这些变阿玲会造成意想不到的错误。

6.堆 heap

堆是最灵活的一种内存,他的生命周期完全由使用者控制,标准的C语言提供了一下几个函数:

  • malloc 用来分配一块指定大小的内存
  • realloc 用来调整/重分配一块存在的内存
  • free 用来释放不再使用的内存

使用堆的时候请注意以下问题。
      malloc/free要配对使用,内存分配之后不释放称为内存泄漏,内存泄漏多了迟早出现"out of memory"的错误,再分配内存就会失败。当然释放时也只能释放分配出来的内存,释放无效的内存或者重复free指令都是不行的,会造成程序崩溃。分配多少内存就是用多少内存,分配了100B就只能使用100B,不管是读还是写,都只能在这个范围内,读多了会读到随机的数据,写多了就对造成随机的破坏,这种情况我们称为缓存区溢出(Buffer Overflow),这是非常严重的,大部分安全问题都是由缓存区溢出引起的。手动检查有没有内存溢出或者缓存区溢出是很困难的,幸好有些工具可以使用。例如Linux下的valgrind,它的使用方法很简单。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

独尊0136

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

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

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

打赏作者

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

抵扣说明:

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

余额充值