C++中三种创建对象的方法【转】
我们都知道C++中有三种创建对象的方法,如下:
#include <iostream>
using namespace std; class A
{
private:
int n;
public:
A(int m):n(m)
{
}
~A(){}
}; int main()
{
A a(); //栈中分配
A b = A(); //栈中分配
A* c = new A(); //堆中分配
delete c;
return ;
}
第一种和第二种没什么区别,一个隐式调用,一个显式调用,两者都是在进程虚拟地址空间中的栈中分配内存,而第三种使用了new,在堆中分配了内存,而栈中内存的分配和释放是由系统管理,而堆中内存的分配和释放必须由程序员手动释放,所以这就产生一个问题是把对象放在栈中还是放在堆中的问题,这个问题又和堆和栈本身的区别有关:
这里面有几个问题:
1.堆和栈最大可分配的内存的大小
2.堆和栈的内存管理方式
3.堆和栈的分配效率
首先针对第一个问题,一般来说对于一个进程栈的大小远远小于堆的大小,在linux中,你可以使用ulimit -s (单位kb)来查看一个进程栈的最大可分配大小,一般来说不超过8M,有的甚至不超过2M,不过这个可以设置,而对于堆你会发现,针对一个进程堆的最大可分配的大小在G的数量级上,不同系统可能不一样,比如32位系统最大不超过2G,而64为系统最大不超过4G,所以当你需要一个分配的大小的内存时,请用new,即用堆。
其次针对第二个问题,栈是系统数据结构,对于进程/线程是唯一的,它的分配与释放由操作系统来维护,不需要开发者来管理。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时,这些存储单元会被自动释放。栈内存分配运算内置于处理器的指令集中,效率很高,不同的操作系统对栈都有一定的限制。 堆上的内存分配,亦称动态内存分配。程序在运行的期间用malloc申请的内存,这部分内存由程序员自己负责管理,其生存期由开发者决定:在何时分配,分配多少,并在何时用free来释放该内存。这是唯一可以由开发者参与管理的内存。使用的好坏直接决定系统的性能和稳定。
由上可知,但我们需要的内存很少,你又能确定你到底需要多少内存时,请用栈。而当你需要在运行时才知道你到底需要多少内存时,请用堆。
最后针对第三个问题,栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率 比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在 堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会 分 到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
再补充几点。
平时使用容器的时候,都会直接使用上述第一种方法定义。
比如:
std::vector<TestBase> a;
那么如果a要存很大的东西,会不会爆栈呢。
其实是不会的,虽然a是在栈上分配的内存,但是a所占的栈空间是很小的。
std::cout << sizeof(a) << std::endl;
输出: 24
比如vector,无论push了多少东西,存的类有多大,都在在堆上new的,而在栈上所占用的空间就只有三个指针的大小。
当然你也可以new 一个容器。这样占用栈的空间就只有一个指针的大小了。
C++中三种创建对象的方法【转】的更多相关文章
- iOS——浅谈iOS中三种生成随机数方法
ios 有如下三种随机数方法:
- Sql Server中三种字符串合并方法的性能比较
文章来自:博客园-DotNet菜园 最近正在处理一个合并字符吕的存储过程,在一个测试系统的开发中,要使用到字符串合并功能,直接在Sql中做.示例:有表內容﹕名称 內容1 abc1 ...
- C++中三种传递参数方法的效率分析
众所周知,在C++中有三种参数传递的方式: 按值传递(pass by value) #include <iostream> using namespace std; void swap(i ...
- 转 java中5种创建对象的方法
作为Java开发者,我们每天创建很多对象,但我们通常使用依赖管理系统,比如spring去创建对象.然而这里有很多创建对象的方法,我们会在这篇文章中学到. Java中有5种创建对象的方式,下面给出它们的 ...
- iOS-浅谈iOS中三种生成随机数方法
ios 有如下三种随机数方法:
- 分布式环境中三种Session管理方法的使用场景及优缺点
在分布式环境,管理Session通常使用下面三种方式: 一.Session Replication 方式管理 (即session复制) 简介:将一台机器上的Session数据广播复制到 ...
- JavaScript 三种创建对象的方法
JavaScript中对象的创建有以下几种方式: (1)使用内置对象 (2)使用JSON符号 (3)自定义对象构造 一.使用内置对象 JavaScript可用的内置对象可分为两种: 1,JavaScr ...
- js中三种全局变量声明方法
声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量.该方式即为显式声明详细如下: <script> ...
- C#三种创建对象方法所需时间比较。。。。。
C#创建对象的三种方法 new().Activator.Assembly,接下来通过代码直接来看看运行的速度.... 首先,先看看三种创建对象实例的方法: //new(); public stati ...
随机推荐
- C#自定义事件 范例:监视变量变化
很多时候我们需要程序具有一种功能,就是当满足某一条件时触发某个动作,使用C#的事件机制就可以达到这个目的下面的例子是一个很好的演示,这段代码实现了对一个变量的监视,一旦变量发生改变,就触发动作 定义事 ...
- POI导出Word插入复选框
POI功能比较强大,但是有些不常用功能比如插入特殊符号,不知道API怎么调用 Word里要插入复选框,首先想到的是POI有没有提供现成的API,搜了一番,貌似都说不直接支持 http://stacko ...
- win用VNC远程Ubuntu教程
转载:https://blog.csdn.net/jiangchao3392/article/details/73251175 1.安装Xrdp Windows远程桌面使用的是RDP协议,所以ubun ...
- PCL(Point Cloud Library)的第三方库简单介绍(boost,eigen,flann,vtk,qhull)
PCL由于融合了大量的第三方开源库,导致学习成本升高~在学习之前我们最好还是了解一下这些库都是干嘛的,以便有的放矢.在之后更好的使用 boost: C++的标准库的备用版,擅长从数学库到智能指针,从模 ...
- 【VirtualBox】共享文件夹失效问题
fix: sudo ln -f -s /opt/VBoxGuestAdditions-5.1.20/lib/VBoxGuestAdditions/mount.vboxsf /sbin/mount.vb ...
- 2015-10-07:几乎100%肯定:百度网盘在夜间的时段是不限速的:早晨7点前很轻松达到3M/S,7点后就降低到1M/S了,白天才400K/S左右
最近发现(2015-10-07)几乎100%肯定:百度网盘在夜间的时段是不限速的:早晨7点前很轻松达到3M/S,7点后就降低到1M/S了,白天才400K/S左右
- pycharm 对代码做静态检查
对于下面这种情况,java c这些提前编译的语言,不给你运行机会就立马报错了,但对于动态语言运行之后才能报错,用运行的方法来检查代码错误是在是太坑了,这是py对比静态语言的巨大劣势,尤其是代码文件多行 ...
- GOF---Java开发中的23种设计模式详解
表点 设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式 ...
- GreenPlum数据库安装
第一章 文档概述 本文描述适用于Greenplum4.0以上版本的安装操作.所涉及到的操作系统相关参数调整,主要针对Redhat Linux操作系统. 第二章 安装介质 操作系统:Cent ...
- Splash plugins_enabled 属性
plugins_enabled属性可以控制浏览器插件(如 Flash 插件)是否开启.默认情况下,此属性是 false ,表示不开启. function main(splash, args) spla ...