c++初学者,深入理解内存

来源:互联网 发布:js中数组join 编辑:程序博客网 时间:2024/05/23 19:26

c++初学者往往对内存理解不清楚,对于其感到神秘。下面我们可以慢慢看到内存在编程中的可操作性,然后你就知道其实内存也就那么回事了。

      首先,我们写个c++hello world程序。那么这断代码放在哪里?汇编里面学过:代码段。其实这些东西我们不关心。我们关心的是数据存放的地方和结构。聪明的你猜对了,对,数据放在数据段。这是废话,起始这是很重要的,计算机体系结构讲到的哈佛结构就是这个意思。

      好,我们开始关心数据存放。首先程序一般的数据是以栈的形式存放的,学过编译的你也许有点印象,一个函数A调用另一个函数BB再调用C。那么A中变量全部放在一块区间,B就放在紧接着的空间。C的数据空间在B后面。进入C的时候,对于B中的数据不可见。但可以使用全局变量?对,全局变量可以算令一块空间,不在此堆栈,应该叫静态区。这样做就让传参和返回值能很容易实现,这不是重点,大家可以自己研究。

       然而程序可以用new申请空间,这些如果也放在栈里面,这样这个栈就不好建了。于是编系统的大牛们把所有new的数据放在一个堆里面,为什么用堆,便于申请和回收,我们不做详细解释。

       总结一下:

       全局变量 à     静态存储区

       局部变量 à   

       动态申请 à   

 

       再来看存储数据结构:

                     大小        赋值        内存实际存储内容(全部是01

                                          |第一字节   | |第二字节   | |第三字节   | |第四字节   |

                     aasc码是97,换算成16进制是0x61,2进制是0110 0001

char              1字节     a            |0110 0001|

 

       short      2字节     2            |0000 0000| |0000 0010|

       int          4字节     3            |0000 0000| |0000 0000| |0000 0000| |0000 0011|

 

而负数是补码表示的,相信你们比我更会算。

我们可以把任何变量看做指针。而一个int型变量可以算个0级指针。比如说int a =0;这是告诉编译器,有个a的变量,内容是0;但是要找到a的内容,让你设计,你会怎么设计,很简单嘛,记住它内存的地址。你根据地址去取数据。为什么不直接记住内容?a就是0嘛,但是你在代码段记住内容,第二a值变动了,你怎么记?跟着变?这么编译器得耗费多大功夫给你干这事,自己想象去。而int *a;更加是一种记住别人位置的东西。他是记住一个指针地址的东西,这些东西非常好用。

 

关于数据使用。一般的编网络程序,你必须得,进行各种填充。比如一个ip = “10.0.0.1”,网络报文发过来,在内存存放的值是一个4字节的数,上面的ip 实际上内存里面是 1* 256*256*256+10。大端小端问题自己可以看看,但xpfedora应该都是小端,和我说的那个数据应该一致。而我发包时候怎么把它拿过来呢?其实很简单,用一个指针指向它,就可原封不动的拿过来。unsigned int *a =那片内存,然后对指针取内容,很轻松的可以拿到那个数据,然后复制给想要的地方。*a就是取内容了,学过c++,这点是应该知道的吧。比如要想把一个char b = ‘a’;打出其asc码,怎么办,把它转换成int就好了,这样打出的是97,想打出61只要换个hex格式就行。换而言之,你知道某块内存的数据,就可以把它以任何你想要的格式拿出来。用指针指过去(如果目标类型和想转换成为的类型不一致就用强制类型转换),然后取内容。

理解上面这些才能算c++入门。