对象模型是面向对象程序设计语言的一个重要方面,它会直接影响面向对象语言编写程序的运行机制及对内在的使用机制,因此了解对象模型是进行程序优化
的基础。分析一般意义上程序中的数据在内存中的分布,以及程序使用的不同种类的内存等基本的概念。了解对象的生命周期,以及对象的内存布局。只有通过深入
的学习C++对象模型,才能避免程序开发中一些不易察觉的内存错误 。从而达到改善程序性能,提高程序的质量。
程序使用内存区
一
个种序占用的内存区一般分为,全局(静态)数据区,常量数据区,代码区,栈,堆,我们所编写的程序就放在代码区中,而程序的数据要根所相应的数据类型,存
储至不同的内存区中,在C++语言中,数据有不同的分类方法,例如常量和变量,全局数据和局部数据,以及静态数据和非静态数据.另外,还有程序运行过程中
动态产生和释放的数据,这些数据放在不同的数据区中。
全局(静态)数据区存储全局变量及静态变量(包括全局静态变量和局部静态变量)。
常量数据区中存储程序中的常量字符串等。
栈中存储自动变量或者局部变量,以及传递的函数参数等,而堆是用户程序控制的存储区,存储动态产生的数据。
通过Memory.cpp来测试可以清晰看出,内存区的数据的存放
#include <stdio.h>
#include <stdlib.h>
int nGlobal = 100;
int main(void )
...{
char *pLocalString1 = "LocalString1";
const char *pLocalString2 = "LocalString2";
static int nLocalStatic = 100;
int nLocal = 1;
const int nLocalConst = 20;
int *pNew = new int[5];
char *pMalloc = (char *)malloc(1);
//全局变量(nGlobal)、静态变量和局部的静态变量(nLocalStatic)
printf("global variable: 0x%x ", &nGlobal);
printf("static variable: 0x%x ", &nLocalStatic);
printf("local expression 1: 0x%x ", pLocalString1);
printf("local expression (const) : 0x%x ", pLocalString2);
//堆内存
printf(" ");
printf("new: 0x%x ", pNew);
printf("malloc: 0x%x ", pMalloc);
printf(" ");
printf("local pointer(pNew): 0x%x ", &pNew);
printf("local pointer(pLocalString2): 0x%x ", &pLocalString2);
printf("local pointer(pLocalString1): 0x%x ", &pLocalString1);
printf("local variable(nLocal): 0x%x ", &nLocal);
printf("local pointer(pMalloc): 0x%x ", &pMalloc);
printf("local const variable: 0x%x ", &nLocalConst);
return 0;
}
输出为:
global variable: 0x417000
static variable: 0x417004
local expression 1: 0x4158d4
local expression (const) : 0x4158c4
new: 0x32a10
malloc: 0x32a50
//边界对齐通过New申请了5个整数需要的内存,通过
malloc申请了1个字节。这里的地址相差32个字节,如果按正常算应该是20个字节为0x14,malloc申请地址应该从new后的20个字节
32a24开始,但占据32个字节的内存(0x32a10~0x32a50),即在内存分配时按16个字节对齐。
local pointer(pNew): 0x13ff30
local pointer(pLocalString2): 0x13ff54
local pointer(pLocalString1): 0x13ff60
local variable(nLocal): 0x13ff48
local pointer(pMalloc): 0x13ff24
local const variable: 0x13ff3c
内存对齐方式虽然浪费一些内存,但由于CPU在对齐方式下运行比较快,简化了处理器和存储器系统之间接口的硬件设计。如,假设处理器总是从存
储器中取8个字节出来,则地址必须为8的倍数。如果我们能合保证所有的double都将它们的地址对齐成8的倍数,那么就可以用一个存储器操作来读或写值
了。否则,我们可能需要执行两次存储器访问,因为对象可能分放在两个8字节存储器块中。
阅读(922) | 评论(0) | 转发(0) |