您的位置:首页 > 其它

内存

2015-12-03 19:00 344 查看
谈内存之前,首先了解一下C++的类型在不同编译中的所占字节:

1.字节和字长

字节,八位就是一个字节,是固定概念。字长是指计算机一次能处理的二进制数据的长度,是一个非固定的概念。例如,8位计算机的字长为8bit,即一个字节, 32位计算机的字长位32bit,即4个字节,同理,64位计算机的字长为64bit,即8字节。

2.char类型始终是一个字节,即8bit。

3.int、short int和long int

通常int占4个字节,short占2个字节,long占4个字节或8个字节(在32位机器中为4个字节)。

4.浮点型float、双精度double、和长双精度long double

典型情况下,float 为4个字节,double是8个字节,long
double为12个字节或16个字节。


C/C++仅仅定义了这些基本数据类型之间的关系,并没有定义严格定义它们的字长。

在不同的平台上,根据编译器不同的实现,它们的字长如下表所示:
数据类型
LP64
ILP64
LLP64
ILP32
LP32
char
8
8
8
8
8
short
16
16
16
16
16
_int32
N/A
32
N/A
N/A
N/A
int
32
64
32
32
16
long
64
64
32
32
32
long long
N/A
N/A
64
N/A
N/A
pointer
64
64
64
32
32
在这张表中,LP64,ILP64,LLP64是64位平台上的字长模型,ILP32和LP32是32位平台上的字长模型。

LP64意思是long和pointer是64位,

ILP64指 int,long,pointer是64位,

LLP指long long和pointer是32-bit的。

ILP32指int,long和pointer是32位的,

LP32指long和pointer是32位的。

32位Windows采用的是ILP32数据模型,64位Windows采用的是LLP64数据模型。

所以,Windows上的32位程序设计和64位程序设计最大的不同(也就是ILP32和LLP64的不同),就在于指针的长度不同??由32位变成了64位。

Win32 API在很多情况下,都需要将整数转换成指针或者相反。在 32 位的硬件上不会有问题,其中指针的大小和整数的大小是相同的,但在 64 位的硬件上却完全不一样。

1.变量在内存中

测试用例:

#include <iostream>
using namespace std;

int main(void)
{
/*栈空间*/
int a = 1;
int b = 2;

int n1[2] = {1,2};
int n2[2][2] = {1,2,3,4};

int *a1 = &a;
int *n = n1;

/*堆空间*/
int *n3 = new int[];
int *n4 = new int[2];

return 0;
}


各变量在内存中的地址:





[b](1) 由内存列表可以看出: [/b]

变量在内存中从高地址向低地址生长,说明存储在栈中

(2) 由红色标志的地址可以看出:

数组本身就是一个地址,所以数组名与取地址的数组名所表示的地址是相同的

(3) 由绿色方框中的地址可以看出:

内存地址是从低地址向高地址生长,说明用new申请的内存是在堆中.

变量及其申请的空间在内存中的具体存储:






每个变量后都有8字节的cc作为间隔.

2.指针在内存中

指针的大小用sizeof可以获取.

指针的大小跟编译器有关,

例如:

用VS2013中的32位编译器编译指针,sizeof(指针)=4

用VS2013中的64位编译器编译指针,sizeof(指针)=8



vs2013编译器调整:








3.复杂指针
在上述程序中添加如下指针:

/*指针*/
//数组指针(本质上是一个指针,而且是一个指向数组的指针)
int (*n5)[2]=n2;
//n5 = n2;
//n5 = &n1;

//指针数组(本质上是一个数组,里面存放的都是指针)
int *n6[2];    //int *(n6[2])  //[]的优先级比*高
n6[0] = n1;
n6[1] = &a;


内存分布: (由于重新编译程序,内存重新分配,所以地址与上面有所不同,这里不想再重新做图了,偷懒了,知道具体分布就ok了)



由此验证指针数组与数组指针的区别.
数组指针:本质上是一个指针,而且是一个指向数组的指针
指针数组:本质上是一个数组,里面存放的都是指针

数组指针:

int (*a)[2]

[2] 用来控制申请内存的长度为2.

(*a)用来控制标识内存的地址,且没有限制.

总结: 相当于限制了申请内存的长度,地址的个数没限制



指针数组:

int *p[4] 相当于int *(p[4]) ,因为[]的优先级比*高.

(p[4]) 相当于限制了申请地址的个数,只能为4.

但是每一个地址所指向的内存是可变的(即内存长度不定).

总结: 相当于限制了申请地址的个数,内存的的长度没有限制

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: