您的位置:首页 > 编程语言 > C语言/C++

C++内存分配机制

2015-04-21 11:35 155 查看
程序运行时需要系统分配内存,那么系统如何为程序分配内存呢?

首先,我们得清楚内存分配方式分为类:静态分配内存和动态分配内存。那么这两种又是个什么东西?好的,基于这个问题我们来看一下他们的定义:

静态分配内存:由编译器根据变量类型来确定分配给变量多少字节的内存区域。

动态分配内存:程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。由于java中的有垃圾回收机制,释放这种事就交给他来做了。

明白了静态和动态的区别,下面我们来谈谈C++中的内部存储区:

分为5类:

一.静态分配区

1.全局变量和静态变量存放区:主要存放定义在所有函数之外的全局变量,以及用static声明的静态变量。变量有效时间直到程序结束。

2.常量存放区:常量是指那些用const关键字修饰的变量。在java中用final关键字来修饰。变量有效时间直到所在块结束,即函数外定义的就直到程序结束,函数中定义的就直到函数调用结束。

3.栈:存放函数中的局部变量以及函数调用时的参数。变量有效时间直到函数结束。

以上就是静态分配所分配的三种内存区域,他们的内存分配在编译阶段完成。清楚了吧。好,下面我们来聊一些与上面知识点相关的东西:const和static的区别。

const:被修饰的变量为常量,只能赋值一次,以后不可更改,与宏定义的效果类似,但作用域和普通变量一样。

static: 被修饰的变量可以保存上一次的执行结果,作用域和普通变量一样。

上段代码:

#include <iostream>
using namespace std;
int global = 0; //存放在全局变量区,值为0
const double pi = 3.14; //存放在静态变量区,值为3.14
int main(){
double plus(int a);
int i; //只是声明了一个变量,值为系统默认添加
int j;
cout << "input 2 number:" << endl;
cin >> i;
cin >> j;

double s1 = 0;//s1存放在栈中,它的值是0
double s2 = 0;
s1 = plus(i);
s2 = plus(j);
cout << s1 << " " << s2 <<endl;

return 0;
}
double plus(int a){
static int count = 0; //存放在静态区,可以保存上一次计算结果
count++;
cout << "run" << count << "times" <<endl;
return a * a * pi;
}

在上面的程序编译阶段静态分配存储是这个样子的



当你运行到函数plus时,系统在栈区s2的上面再为参数a分配内存。

其实在内存当中,这几部分存储区是这样子的,像下面这张图



全局变量和静态变量,从低位地址开始分配,占一块特殊的内存,因为程序要不时地去调用他,知道程序结束,所以特殊照顾了。

堆区,从全局变量和静态变量结束的地方开始分配内存,向下增长。

栈区,从内存高位地址开始分配,向上增长。

.动态分配
4.堆:堆是由new申请的内存,由delete或delete[]负责释放该堆。

5.自由存储区,存储由程序员用malloc/calloc/realloc分配,free释放。如果程序员忘记free了,则会造成内存泄露,程序结束时该片内存会由OS回收。

以上两种内存区在程序运行时进行动态分配。

#include <iostream>
#include <String>
using namespace std;
int main(){
char *p = (char*)malloc(13); //再堆中分配13字节内存空间,并把地址返回给栈中的变量p
p = "Hello World!";
cout << p << endl;
char *q = new char[5]; //在堆中分配5个cha型字节内存空间,并把地址返回给栈中的变量p
q = "I love C++";
cout << q <<endl;

return 0;
}

上面的程序在运行时分配是这样的:



当malloc时,系统把p分配在栈中,并在自由存储区中分配出所需要的内存,将分配地址返回给p中存储,

当new时,系统把q分配在栈中,并在堆中分配所需要的内存,将分配地址返回给q中存储。

有么有明白一点呢?

还有一个问题是int a = 10;类似于这种基本类型存放在哪呢?答案是在栈里,为a分配一块内存,里面存储内容为10。

其实,他有几块存储区并不是重点,重点是理解动态与静态分配内存的过程和区别。

文章到这里也就结束了。在最后抛出一个问题:

1.数组int arry[5] ={1,2,3,4,5,}当中{1,2,3,4,5,}是在哪里开辟内存存储,他既没有new,也没有malloc

2.同样的string s = "Hello World!" 当中的"Hello World!"又是存放在哪里呢?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐