C++对象内存模型1(堆栈模型)(转)
对象内存模型
一. 栈(Stack) VS. 堆(heap)
- 栈
- 由系统自动管理,以执行函数为单位
- 空间大小编译时确定(参数+局部变量)
- 函数执行时,系统自动分配一个stack
- 函数执行结束时,系统立即自动回收stack
- 堆
- 在c++中由程序员手动控制
- 手动分配new和malloc
- 手动释放delete和free
- 具有全局性,总体无大小限制
- 容易造成内存泄露
1. Myclass c(10); // 栈对象,空间大小在编译时确定,函数执行结束,系统立即回收
2.
Myclass* func(){
Myclass c();
return &c; //返回栈内存地址,指针悬浮,极端错误!
}
3.
Myclass func(){
Myclass c();
Aclass a();
c.pa = &a; //指向栈(local)对象,错!
return c;
}
结论: 指针指向栈对象,就要极度小心,一般会有问题!
4.
Myclass* func(){
Myclass *pa = new Myclass();
return pa; //小范围看没问题,但违背谁分配谁释放原则,此例接受者不知道要delete
}
总结返回指针问题:
返回栈指针: 完全错误
返回堆指针:释放可能有问题 ,易造成内存泄露
故一般不推荐
5 堆对象内存模型
6. 栈对象内存模型
二. 变量模型与使用 (对象,指针,引用; 声明,传参,返回值)
1. 声明与符号
“*” : 声明时,指针
用在指针前,解指针
“&”: 声明时,引用
用在对象前,取地址
MyClass c; //对象,一定在栈上 MyClass* pc; //指针,要问自己是栈指针,还是堆指针 MyClass& c2 = c; //引用,要问自己是栈引用,还是堆引用。本例为栈引用
// 举例堆引用 Myclass *pc2 = new Myclass(); Myclass& c3 = *pc2; c3为堆引用 c = *pc; //解指针, 可指向堆对象,也可以指向栈对象
//pc指向哪里,*pc即为指向哪里的对象(堆/栈)
//又c在栈上 再调用拷贝构造函数完成 c = *pc pc = &c; //取地址
2 传参分析
//对象
void func1(MyClass c) { // 对象往往较大,开销大,一般不!
}
//指针
void func2(MyClass* pc) { // 成本ok,但无法区分堆/栈,有delete问题
}
//引用
void func3(MyClass& mc) { //推荐,不想双向传递用const
}
const& 为 pass by value好的替代品
void func3(const MyClass& mc) {
}
调用方法:
MyClass c1;
func1(c1); //调用拷贝构造
func2(&c1); //不调用拷贝构造
func3(c1); //不调用拷贝构造,注意参数就写值即可,参考笔记2,传递者无需知道接受者的接受方式。乱加符号可能变成取地址了
3. 返回值分析
返回对象分析:
MyClass func1() {
MyClass c1;
return c1; //正确,调用拷贝构造
MyClass* pc2 = new MyClass();
return *pc2; // 返回时调用拷贝构造,结束后pc2就取不到了,内存无法释放,一定存在内存泄露
}
返回指针分析:
MyClass* func2() {
MyClass c1;
return &c1; //极端错误,返回栈对象指针
MyClass* pc2 = new MyClass();
return pc2; //不推荐,可能内存泄露,违背谁调用谁释放原则
}
故返回指针一般不推荐
返回引用分析:
MyClass& func3() {
MyClass c1;
return c1; // 极端错误,栈对象结束就消亡了
MyClass* pc2 = new MyClass();
return *pc2; //可能存在内存泄露,有办法取到pc2,但一般人不会去做,也不知道要做
}
返回传入参数的引用,ok且推荐,常见还有this指针
MyClass& func4(MyClass& c) {
return c;
}
C++对象内存模型1(堆栈模型)(转)的更多相关文章
- JVM 系列(4)一看就懂的对象内存布局
请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · AndroidFamily 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭锐] ...
- C++/C#中堆栈、对象内存模型、深浅拷贝、Array.Clone方法
转载自:http://blog.csdn.net/jarvischu/article/details/6425534 目录 1. C++/C#中对象内存模型................. ...
- C++对象内存模型1(堆栈模型)
对象内存模型 一. 栈(Stack) VS. 堆(heap) 栈 由系统自动管理,以执行函数为单位 空间大小编译时确定(参数+局部变量) 函数执行时,系统自动分配一个stack 函数执行结束时,系统立 ...
- C#的对象内存模型
转载自:http://www.cnblogs.com/alana/archive/2012/07/05/2577893.html C#的对象内存模型: 一.栈内存和堆内存1.栈内存 由编译器自动分配和 ...
- C++对象内存模型2 (虚函数,虚指针,虚函数表)
从例子入手,考察如下带有虚函数的类的对象内存模型: class A { public: virtual void vfunc1(); virtual void vfunc2(); void func1 ...
- (转)c#对象内存模型
对象内存模型 C#的对象内存模型写这篇博客的主要目的是为了加深自己的理解,如有不对的地方,请各位见谅. C#的对象内存模型: 一.栈内存和堆内存1.栈内存 由编译器自动分配和释放,主要用来保存一些局部 ...
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响
首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...
- Swift 对象内存模型探究(一)
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/zIkB9KnAt1YPWGOOwyqY3Q 作者:王 ...
- 对C++对象内存模型造成的影响(类/对象的大小)
首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...
随机推荐
- day04——列表、元组、range
day04 列表 列表--list 有序,可变,支持索引 列表:存储数据,支持的数据类型很多:字符串,数字,布尔值,列表,集合,元组,字典,用逗号分割的是一个元素 id() :获取对象的内存地址 ...
- LeetCode 5216. 统计元音字母序列的数目(Java)DP
5216. 统计元音字母序列的数目 给你一个整数 n,请你帮忙统计一下我们可以按下述规则形成多少个长度为 n 的字符串: 字符串中的每个字符都应当是小写元音字母('a', 'e', 'i', 'o', ...
- 不会前后端,用vps搭建个人博客(二)
<接上一篇> 四.添加网页内容 1.下载安装WordPress 输入以下命令: wget https://wordpress.org/latest.tar.gz 当然你也可以用浏览器进 ...
- Spring boot java.lang.NoClassDefFoundError: org/springframework/boot/bind/RelaxedPropertyResolver
Spring boot 2.0.3 RELEASE 配置报错 java.lang.NoClassDefFoundError: org/springframework/boot/bind/Relaxed ...
- Docker 安装入门 Centos Linux安装Docker 部署mysql
这次购买了阿里云云服务器,并且安装了Centos 7.5 学习使用Docker, 确认版本信息 Docker 运行在 CentOS 7 上,要求系统为64位.系统内核版本为 3.10 以上. Dock ...
- C# 利用MS的 EntLib的Database类编写的DbHelper
C# 利用MS的 EntLib的Database类编写的DbHelper,由于MS的EntLib对Oracle.SQL Server和MySql已经封装,所以可以该DbHelper可以适用这三种数据库 ...
- DOS之cd命令
cd命令是改变子目录的命令, 下面是cd命令的常见用法 cd/?可显示帮助信息 cd 返回到当前所在的根目录中 cd.. 返回上一层目录 cd +目录名,进入下一层目录 驱动器:,进入到另一个驱动器 ...
- python入门基础 02
目录 1.while 2.字符串格式化 3.运算符 4.编码初始 总结 1.while # while -- 关键字 (死循环) # # if 条件: # 结果 # # while 条件: # 循环体 ...
- LocalDateTime&LocalDate&LocalTime
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");LocalDateTime ti ...
- 【openshift】OC命令部署Openshift
OC命令部署Openshift # install openshift wget -c https://github.com/openshift/origin/releases/download/v3 ...