内存管理是C++最重要的一部分,也是C++最有争议的问题。用户可以从内存管理获得更大的自由度及更好的性能优化,但同时也带来极大的隐患,如果用不好很容易造成内存的泄露,因此,如意要真正掌握C++的核心,必须要精通C++的内存管理机制。目前的Java和.NET都提供了内存管理的自动机制,但是是以牺牲对使用内存的支配权为代价的,放弃了C++的绝对优越性。
1、 程序的内存区
一般而言,计算机的内存区域由代码和数据组成,这两个部分也是影响一个程序所需内存的重要因素。代码是允许的指令,例如数学运算、比较、跳转即函数调用等,其大小通常是由程序的功能及复杂程度决定的。当然,正确地使用程序的编写技巧及编程语言的语法特性会优化产生代码的大小,数据是代码要处理的对象。一个程序占用的内存区域一般分为5种,它们是:全局/静态数据区、常用数据区、代码区、栈、堆等。程序的代码存储在代码区中,而程序的数据则要根据数据种类的不同,存储在不同的内存区。
2、 内存的分配方式
① 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如,全局变量、static变量及字符串常量。这部分存储区是在程序编译阶段已分配好,在整个程序运行过程中始终存在,用于存储全局变量、静态变量及字符串常量等。其中,字符串常量的存储区域是不可修改的内存区域,如下面的这段代码会导致程序运行中断:
#include <iostream>
using namespace std;
int main()
{
//指向一个字符串常量
char* pLocalString = "this is a test";
/**//* 下面这句提示错误:error C2440: '=' :
* cannot convert from 'const char' to 'char *'
* 试图修改不可修改的内存区
*/
pLocalString='#';
//cout<<pLocalString<<endl;
return 0;
}
②从栈上创建。在执行函数时,函数局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
③在栈上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多的内存,程序员自己负责在何时用free或delete释放内存。动态内存生存期由程序员决定,使用非常灵活,但问题也最多,很容易造成内存泄露。
3、 代码参考
通过下面的程序,来说明各种类型的数据在内存中的位置。
#include <stdio.h>
#include <stdlib.h>
int nGlobal=100;
int main()
{
char* szLocalString1="LocalString1";
const char* szLocalString2="LocalString2";
static int nStatic =100;
int nLocal=1;
const int nLocalConst=200;
int* pNew=new int[5];
char* szMalloc=(char*)malloc(1);
printf("global variable:0x%x\n",&nGlobal);
printf("static variable:0x%x\n",&nStatic);
printf("\n");
printf("local expression 1:0x%x\n",szLocalString1);
printf("local expression 2:0x%x\n",szLocalString2);
printf("\n");
printf("new 0x%x\n",&pNew);
printf("local pointer(szLocalString1):0x%x\n",&szLocalString1);
printf("local pointer(szLocalString2):0x%x\n",&szLocalString2);
printf("\n");
printf("local variable:0x%x\n",&nLocal);
printf("local pointer(szMalloc):0x%x\n",&szMalloc);
printf("local const variable:0x%x\n",&nLocalConst);
return 0;
}
输出结果如下:
想要获得更多内容,可点击:
《Visuanl C++代码参考与技巧大全》学习笔记——索引随笔