对象内存模型

一. 栈(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;
}

结论: 指针指向栈对象,就要极度小心,一般会有问题!

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(堆栈模型)的更多相关文章

  1. JVM 系列(4)一看就懂的对象内存布局

    请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · AndroidFamily 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭锐] ...

  2. C++/C#中堆栈、对象内存模型、深浅拷贝、Array.Clone方法

    转载自:http://blog.csdn.net/jarvischu/article/details/6425534 目录 1.      C++/C#中对象内存模型................. ...

  3. C++对象内存模型1(堆栈模型)(转)

    对象内存模型 一. 栈(Stack) VS. 堆(heap) 栈 由系统自动管理,以执行函数为单位 空间大小编译时确定(参数+局部变量) 函数执行时,系统自动分配一个stack 函数执行结束时,系统立 ...

  4. C#的对象内存模型

    转载自:http://www.cnblogs.com/alana/archive/2012/07/05/2577893.html C#的对象内存模型: 一.栈内存和堆内存1.栈内存 由编译器自动分配和 ...

  5. C++对象内存模型2 (虚函数,虚指针,虚函数表)

    从例子入手,考察如下带有虚函数的类的对象内存模型: class A { public: virtual void vfunc1(); virtual void vfunc2(); void func1 ...

  6. (转)c#对象内存模型

    对象内存模型 C#的对象内存模型写这篇博客的主要目的是为了加深自己的理解,如有不对的地方,请各位见谅. C#的对象内存模型: 一.栈内存和堆内存1.栈内存 由编译器自动分配和释放,主要用来保存一些局部 ...

  7. 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响

    首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...

  8. Swift 对象内存模型探究(一)

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/zIkB9KnAt1YPWGOOwyqY3Q 作者:王 ...

  9. 对C++对象内存模型造成的影响(类/对象的大小)

    首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(member),#pragma pack(n) ...

随机推荐

  1. 'System.Web.Http.GlobalConfiguration' does not contain a definition for 'Configure'

    It needs the system.web.http.webhost which is part of this package. I fixed this by installing the f ...

  2. SQL Server 索引 之 书签查找 <第十一篇>

    一.书签查找的概念 书签可以帮助SQL Server快速从非聚集索引条目导向到对应的行,其实这东西几句话我就能说明白. 如果表有聚集索引(区段结构),那么书签就是从非聚集索引找到聚集索引后,利用聚集索 ...

  3. 第二百三十二天 how can I 坚持

    早上竟然飘起了大学,可是就下了一会,没有一点学的痕迹. 博客园真不知道怎么回事了,字真的好小了. 晚上回来心情好不好,感觉好累,最近不知道怎么了,约罗娜出来吃个饭怎么都约不出来,咋办呢.哎,愁人. 最 ...

  4. SCU 4440 分类: ACM 2015-06-20 23:58 16人阅读 评论(0) 收藏

    SCU - 4440 Rectangle Time Limit: Unknown   Memory Limit: Unknown   64bit IO Format: %lld & %llu ...

  5. POJ 3304 Segments (直线和线段相交判断)

    Segments Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7739   Accepted: 2316 Descript ...

  6. 操作失败,没有该服务权限![ 机构号:99 ,用户ID:50000009 ,服务号:0101030112 ]

    操作失败,没有该服务权限![ 机构号:99 ,用户ID:50000009 ,服务号:0101030112 ] 此时我们可以把代码 SERVICE_NO 改成 10个0 即 0000000000 ,就可 ...

  7. AutoCAD.NET 不使用P/Invoke方式调用acad.exe或accore.dll中的接口(如acedCommand、acedPostCommand等)

    使用C#进行AutoCAD二次开发,有时候由于C#接口不够完善,或者低版本AutoCAD中的接口缺少,有些工作不能直接通过C#接口来实现,所以需要通过P/Invoke的方式调用AutoCAD的其他DL ...

  8. 实时监控MySql状态

    大多网站的性能瓶颈都会出在数据库上,所以想把Mysql监控起来,就搜索了下相关资料. 后来和同事讨论了下cacti和nagios有些老套和过时,graphite比较时尚,然后就搜了下相关的资料,最后搞 ...

  9. HDU1003前导和

    简单维护前导和 #include<stdio.h> int main() { ],cas,key=; scanf("%d",&cas); while(cas-- ...

  10. SVN安装与使用

    来自:http://www.cnblogs.com/xiaobaihome/archive/2012/03/20/2407610.html SVN服务器搭建和使用(一) Subversion是优秀的版 ...