8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

主要讨论C语言怎样组织正在运行的程序的数据结构的细节。

我们知道知道在UNIX操作系统中,一个C语言文件经过预处理(cpp),编译(cc1),汇编(as)和链接(ld)后可以得到可执行文件a.out。我们可以用size命令(或nm、dump)检查可执行文件,它会告诉你这个文件中的三个段(文本段.text,数据段.data,.bss段)的大小。文本段包含程序的指令。由于程序的文本内容和大小都不会变化,链接器把指令直接从文件拷贝到内存中,不再处理。数据段包含经过初始化的全局和静态变量以及它们的值。BSS段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段之后。当这个内存区进入程序的地址空间后全部清零,通常是memset全部置0。通常把数据段和BSS段统一称为数据区。上面这些内容可以通过size命令很直观的查看与验证。除了上面提到的程序指令、全局和静态变量,我们还有局部变量等数据需要存储。这就引出了堆栈段(stack)和堆空间(heap)。下面将详细讨论数据区、堆栈段和堆空间。

1.数据区存放着全局变量与静态变量,包括初始化和未初始化。其中未初始化的在进入程序地址空间的时候统一清零。这些数据的生命周期都是主程序运行时间。所谓静态变量,是指由static修饰的变量,可以是全局变量,也可以是局部变量。当修饰子函数的局部变量的时候,如果有初始化的话只在第一次进入子函数的时候执行初始化语句,并且在子函数退出的时候依然有效。关于static的另一个作用便是对链接器不可见,这个在以后再说。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17void ()

{

static int a = 0;

a ++;

printf("%dn", a);

}

int main()

{

foo();

foo();

foo();

return 0;

}

2.堆栈段有三个主要的用途:一是为函数内部声明的局部变量(也称“自动变量”)提供存储空间;二是在进行函数调用时,堆栈存储与此相关的一些维护性信息。这些信息被称为堆栈结构(stack frame),或者过程活动记录(precedure activation recored),其中包括函数调用地址、任何不适合装入寄存器的参数以及一些寄存器的保存;三是用作暂时存储区。有时程序需要一些临时存储,比如算术表达式计算。值得注意的是堆栈的入栈是由高地址到低地址,并且局部变量的生命周期在子函数退出的时候也释放了。下面看一个程序1

2

3

4

5

6

7

8

9

10

11

12

13

14

15#include <stdio.h>

int (int i)

{

volatile int a = 1;

volatile int b[2] = {0};

return b[i];

}

int main()

{

int b = foo(2);

printf("%dn", b);

return 0;

}

由于C语言中对数组越界并不会作检查,所以上述程序是可以编译通过并执行的。

volatile是为了防止编译器对代码进行优化,我们来看下foo子函数的堆栈段的情况,由高到低,压入i,a,b[1],b[0],则i==2时,返回的实际上是a。

上面提出局部变量的生命周期,如果一个函数返回了一个局部变量会怎么样呢?1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22int foo1()

{

int a = 100;

return a;

}

int *foo2()

{

int a = 101;

return &a;

}

int main()

{

int *y = foo2();

int x = foo1();

printf("%d, %dn", x, *y);

return 0;

}

两个函数是不一样的,第一个函数返回int型变量,第二个函数返回给一个指针,指向int类型。第一个函数是没有错的,return的时候return的是局部变量a的一个拷贝。而第二个函数返回了局部变量的地址,这是很不安全的。由于函数foo()退出后,局部变量a的地址不受保护,可能会被用作他用,如上面的程序先调用foo2(),再调用foo1()时,把之前的y指向的地址的内容修改了,所以上述程序输出为100, 100。

是不是感觉不过瘾,那再来一个1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19void foo1()

{

int a = 100;

}

void foo2()

{

int a;

printf("%dn", a);

}

int main()

{

foo1();

foo2();

return 0;

}

如果根据第二个例子,我们可以很容易推出结果是:100。但是结果对吗?跑一下就知道了,gcc -O2 test test.c。这里加入了优化选项,从程序中可以看出foo()函数其实什么都没有做,经过编译器可能直接路过foo1(),执行foo2(),所以结果是个随机数。验证也很简单,在foo1()中对a进行一次相关操作就好了。好了,这个有点涉及程序优化了,以后再说。

3.堆(heap)空间用于动态内存的分配,用于malloc相关函数。上面提到堆栈段,注意堆栈段就是栈,是向下生长的,而堆是向上生长的,正好形成一个闭区间。当我们调用malloc等分配内存的时候,要进行检查,因为如果分配失败的话,返回NULL指针,访问的话就会出现段错误了。还有一点要注意是内存泄漏,不用的时候需要显示free()释放。有些语言是加入了垃圾回收机制的,如LISP。对了,还有一点需要提防的就是野指针。野指针在我们进行free之后,指针的指向还是没有变的,所以需要手动置为NULL。

上面主要对C语言运行时的几个段进行一些讨论,当然更深入的学习还是要靠大家自己去实验。

参考:《C专家编程》,《深入理解计算机系统》

c语言运行时内存不够,浅析C语言运行时内存管理相关推荐

  1. c语言中用指针的必要性,浅析C语言使用指针的必要性.pdf

    第 21 卷第 8 期长春大学学报Vol 21No 8 2011 年 8 月 JOURNAL OF CHANGCHUN UNIVERSITYAug 2011 收稿日期 2011 06 20 作者简介 ...

  2. java内存模型浅析_浅谈java内存模型

    不同的平台,内存模型是不一样的,但是jvm的内存模型规范是统一的.其实java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改.总结jav ...

  3. c语言循环结构常用语句,浅析C语言三种循环结构语句

    摘 要: C语言是一种广泛使用的高级程序设计语言,文章对C语言中三种循环结构语句进行了分析和比较,使学生更容易理解和掌握. 关键词: C语言 for循环 while循环 do-while循环 一.引言 ...

  4. python变量存储 堆与栈内存内存_浅析JS中的堆内存与栈内存

    最近跟着组里的大佬面试碰到这么一个问题, Q:说说var.let.const的区别 A:balabalabalabla... Q:const定义的值能改么? A:你逗我?不能吧 不知道各位看官怎么想? ...

  5. 浅析R语言非参数检验的多组比较及分面与分组的图形艺术

    浅析R语言多组定量资料非参数检验的多组比较及簇状柱形图显著性字母标记之分面与分组的图形艺术 R语言多组定量资料非参数检验的多组比较 非参数检验的应用 本流程是在刘永鑫老师提供的代码资料指导下完成 测试 ...

  6. error C2057: expected constant expression (C语言中数组的大小可以在程序运行时定义吗? )

    数组的大小可以在程序运行时定义吗? 不.在数组的定义中,数组的大小必须是编译时可知的,不能是在程序运行时才可知的.例如,假设i是一个变量,你就不能用i去定义一个数组的大小: char array[i] ...

  7. JVM-01Java内存区域与内存溢出异常(上)【运行时区域数据】

    思维导图 概述 运行时数据区域 程序计数器 (Program Counter Register) 概念 特征 可能抛出的异常 知识扩展:JIT即时编译 Java虚拟机栈 (Java Virtual M ...

  8. c语言代码存放的区域 堆栈,C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)...

    BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数据段 :数据 ...

  9. 加密保护软件 WinLicense常见问题整理大全(九):在运行时选择WinLicense消息的语言

    WinLicense具有和Themida同级别的保护功能以及授权管理功能.软件功能强大,使用灵活,开发者可以安全地发布软件的试用版和完全版. Q:我想知道是否可以在运行时选择WinLicense消息的 ...

最新文章

  1. Ubuntu16下编译安装Open Babel2.4.1和python绑定
  2. 《中国人工智能学会通讯》——第3章 3.1基于深度学习的网络表示研究进展
  3. 【数据挖掘】卷积神经网络 ( 视觉原理 | CNN 模仿视觉 | 卷积神经网络简介 | 卷积神经网络组成 | 整体工作流程 | 卷积计算图示 | 卷积计算简介 | 卷积计算示例 | 卷积计算参数 )
  4. ffmpeg基本用法
  5. 679. 24 Game 24 点游戏
  6. window.onbeforeunload() 事件调用ajax的解决方法
  7. 计算机二级offic考试题库2017,2017年9月计算机二级MSOffice考试题「带答案」
  8. 判断微信小游戏用户是否真的分享
  9. 使用selenium启动(无界面)浏览器的隐私模式
  10. SVN工作笔记006---SVN提交,提示“remains in conflict”错误
  11. RelativeLayout相对布局
  12. 部署Lync监控报告
  13. TCP连接发送窗口问题思考
  14. C#cmd执行命令隐藏窗口,并保持程序一直运行
  15. VBS脚本病毒原理分析与防范
  16. 2003服务器系统驱动精灵,万能驱动助理 e驱动 6.1.2014.0516 for XP/win2003 32位专版
  17. c语言水文水资源,长江中游水文网
  18. i微信编辑器服务器,i排版微信编辑器
  19. 数据增强方式mosaic(基于yolo4)代码实现python
  20. QT控件学习:QInputDialog

热门文章

  1. PyCharm 查找文件名
  2. from __future__ import absolute_import用法心得小结
  3. 四丶KingFeng搭建+青龙对接kingfeng
  4. linux内存转换成功,linux系统内存转换成硬盘使用
  5. mysql 113_MySQL教程113-MySQL流程控制语句
  6. 很慢怎么办_数学不好怎么办?脑子笨逻辑思维不好,反应很慢该怎么办?
  7. 聊一聊 SpringBoot 自动配置的原理
  8. python counter函数定义_分享几个自己常用的Python高级函数
  9. Linux之grep命令
  10. framebuffer结构体分析