从一个微型例子看“C/C++的内存分配机制”和“数组变量名与指针变量名”
内存分配方式有三种:
- 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
- 在栈上创建。 在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 这个大小在linux上可以使用:ulimit -a | grep stack 来查看
- 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
using namespace std;
char * GetMemory(void){
//p_arr是个数组的起始地址,这个数组的内容是存放在栈上面的。另外,非常值得一
//提的是:系统没有为p_arr单独分配一个指针变量用来存放数组p_arr的起始地址。
char p_arr[] = "p_arr : hello world";
//p_heap是一个指针变量,这个指针变量存在于栈上面,指针变量的值是指向的由
//malloc分配得到的堆上的内存空间的起始地址。
char *p_heap=(char *)malloc(sizeof(char)*20);
//ptr是一个指针变量,这个指针变量存在于栈上面,指针变量的值是指向的后面字符
//串的起始地址,这个字符串是常量,是存在于静态存储区域的,不是在栈上,也不是
//在堆上。
char *ptr = "ptr : hello world";
strcpy(p_heap,"p_heap: hello world");
printf("%08X\n",p_arr);
printf("%08X\n",&p_arr);
printf("%08X\n",p_heap);
printf("%08X\n",&p_heap);
printf("%08X\n",ptr);
printf("%08X\n",&ptr);
puts(p_arr);
puts(ptr);
puts(p_heap);
//return p_arr;
return ptr;
}
int main(){
char * str=NULL;
str = GetMemory();
printf("%08X\n",str);
printf("%08X\n",&str);
puts(str);
return 0;
}
上面程序输出的结果是:
这里面8有8行关于地址的输出,分别描述如下:
- DC726BF0这个地址是栈上面的,函数退出后,这块地址空间就废弃了。
- DC726BF0是栈上面的地址,之所以和上面一样,是因为栈上并没有分配一个单元用来存放数组指针,这个是使用char []和char * 的最根本的区别。
- 0EB29010这个地址是在堆上面的,直到delete才会释放掉这块内存。
- DC726BE8是栈上面的地址,用来存放指针变量p_heap的单元,p_heap的值就是上面堆上内存的地址。
- 004009D8这个地址是静态存储区的,函数退出后不会清除掉
- DC726BE0栈上面的地址,用来存放指针变量ptr的单元,ptr的值就是上面静态的存储区地址
- 004009D8这个是由函数返回的地址,就是上面静态存储区的地址
- DC726C28这个地址是main函数局部变量的存放地址,位置要比栈上的位置低
栈-->main函数局部变量地址-->堆-->静态变量地址
可以看出来,静态地址最低,然后依次是:堆、main、栈。
另外的,还有一个“先声明的变量时在高地址区还是在低地址区”的问题,这个问题要看栈怎么生长的了,如果栈底在高内存,向低地址生长,自然先声明的变量在高地址。例如:在linux中,栈底就是在高地址的,所以后面声明的变量地址就是低地址。此外,在堆上的地址一般是从低到高的。下面的例子可以清晰的看出这两种情况。
class c1
{
public:
int number;
};
main()
{
int a =3;
int b =4;
printf("addr of a on stack: 0x%X\n",&a);
printf("addr of b on stack: 0x%X\n",&b);
c1 * c=new c1();
c1 * d=new c1();
int * e =new int(100);
printf("addr of c on stack: 0x%X--0x%X(on heap)\n",&c,c);
printf("addr of d on stack: 0x%X--0x%X(on heap)\n",&d,d);
}
以上代码的输出:
对于上面的输出解释如下:
- a,b是位于main函数栈上的变量,他们地址的增长方向是从高到低的。另外,也请注意a和b的地址相差的距离是4个字节(虽然是64位机器和OS,但是int占用的空间还是32位)
- c,d是位于main函数栈上的指针变量,同样是从高到低增长。这次要注意,他们相差的距离是8个字节(因为是c和d都是指针变量,要能够存下64位地址长度的数据)
- 最后,要注意c和d指向的结构都位于堆上,这次他们地址的增长方向就是从低到高(从0xE7F1010到0xE7F1030)了。
http://www.cnblogs.com/welkinwalker/archive/2011/01/05/1926203.html
从一个微型例子看“C/C++的内存分配机制”和“数组变量名与指针变量名”相关推荐
- 从一个小例子看贝叶斯公式的应用(学习简单、基础、入门的例子)
#从一个小例子看贝叶斯公式的应用 ###应用Bayesian公式考察如下的实例并回答问题. 张某为了解自己患上了X疾病的可能性,去医院作常规血液检查.其结果居然为阳性,他赶忙到网上查询.根据网上的资料 ...
- 见微智著 - 从一个小例子看Python中的单元测试
单元测试 据统计,由于软件缺陷(bug),美国经济每年在浪费生产力.返工和实际毁坏上损失了数十亿美元.近期最严重的案例是波音737 Max飞机的两次重大坠机事故,共造成了346人死亡.经过初步调查,该 ...
- 一篇文章看明白 Android v1 v2 签名机制
Android - v1 & v2 签名机制 相关系列 一篇文章看明白 Android 系统启动时都干了什么 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制 一篇文章看明 ...
- 在c语言中定义了一个指针变量后,C语言的指针变量
C语言的指针变量 在C语言中,变量是固定范围的存储空间,它存储的是赋给他的值, 比如: int a = ; /* 这里是定义一个整型变量a,并把12这个值存储在a的地址空间上 这个地址空间是系统随机分 ...
- 一个简单的例子看java线程机制
一个简单的例子看java线程机制 作者: zyf0808 发表日期: 2006-03-26 11:20 文章属性: 原创 复制链接 import java.util.*; public class T ...
- 抽象语法树 c语言,一个简单的例子看懂抽象语法树的魔力
在计算机科学中,抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示.它以树状的形式表现编程语言的语法结构,树上的每个 ...
- 一个经典例子让你彻彻底底理解java回调机制
以前不理解什么叫回调,天天听人家说加一个回调方法啥的,心里想我草,什么叫回调方法啊?然后自己就在网上找啊找啊找,找了很多也不是很明白,现在知道了,所谓回调:就是A类中调用B类中的某个方法C,然后B类中 ...
- SAP MM采购定价过程的一个简单例子
SAP MM采购定价过程的一个简单例子 本文以一个简单的例子阐述了SAP MM模块中采购定价的基本原理.本例中,假定采购订单里输入的是含税采购价,然后系统自动计算出物料最终的采购价格(含税价-税额=采 ...
- 用一个实际例子理解Docker volume工作原理
要了解Docker Volume,首先我们需要理解Docker文件系统的工作原理.Docker镜像是由多个文件系统的只读层叠加而成.当一个容器通过命令docker run启动时,Docker会加载只读 ...
最新文章
- 卵巢鸿蒙不全怎么检查,性激素六项如何看黄体功能萎缩不全
- matlab如何判断线性相关,Fisher线性判断之matlab实现
- 粒子群算法求解无约束优化问题 源码实现
- 小师妹学JavaIO之:文件系统和WatchService
- JVectorMap 实现中国地图
- xshell 上下左右键乱码和退格键失效
- oracle数据库进程不释放,Oracle数据库案例整理-Oracle系统运行时故障-无法释放已经结束的进程资源导致进程死锁...
- 自定义封装无人值守Windows10镜像
- 微信小程序教程、微信小程序开发资源下载汇总(6.16日更新,持续更新中……)
- ie工具internet选项安全自定义级别java_activex控件被禁止怎么办
- 还记得maven使用之令人头疼的.lastUpdated文件吗?
- 人人网冷落主业,押注智能硬件
- buctoj-2022寒假集训4
- 服务器重启之后 宝塔面板打不开
- 校招经验 | 三无菜鸡水硕如何拿到多个高薪offer?
- java-net-php-python-20jspm健身网站管理计算机毕业设计程序
- Lycn 2013 with SQL AlwaysOn 「三」后续问题
- Cache replacement policies(缓存替换策略)/ LRU 和 LFU等算法
- java pdf 转txt文件怎么打开_纯Java实现PDF转txt文件
- TensorFlow MASK R-CNN Demo Windows 无痛搭建 (CPU版)
热门文章
- 字节流转换为对象的方法
- 张高兴的 Windows 10 IoT 开发笔记:RTC 时钟模块 DS3231
- 我用Vue2全家桶重写「daza.io」的前端
- (待解决!)jmx在PetClinic中的应用
- Mysql常用语句(记一下,免得忘)
- 洛谷 P1508 Likecloud-吃、吃、吃
- 在Jenkins远程链接Linux系统,然后执行shell命令-亲测可用【转】
- bzoj 5093 [Lydsy1711月赛]图的价值——第二类斯特林数
- mysql5.7 mysql库下面的user表没有password字段无法修改密码
- oracle习题-emp表查询练习