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 ...
随机推荐
- 一个简单的perl程序
和朋友聊天,说perl的神奇,最主要的是一行代码搞定所有. 想想用python3写的测试脚本,觉得还是有点多的,真的用几行代码写一个测试脚本,可以节约不少时间. 当然,网上黑perl的还是很多,不过自 ...
- mac ssh中文乱码解决
网上有如下解决法,至少我没有成功过: vim ~/.bash_profile export LC_ALL='zh_CN.utf8' 来源:http://www.liuhuadong.com/archi ...
- greenplum的用法
gp建表的实例 gp 创建外部表的实例:(外部表不能建立分布键) CREATE EXTERNAL TABLE user_app_tag ( ...
- lrzsz离线安装方法
lrzsz离线安装方法 到网上下载lrzsz安装包,这里以lrzsz-0.12.20.tar.gz为例 2 打开终端 cd 到安装包所在目录 tar zxvf lrzsz-0.12.20.tar.gz ...
- level 6 - unit 2 - 情态动词May
情态动词May 正式的请求/许可 意思为可以 例如我们在机场候机室听广播的时候,在播报航班前经常听到: may i have your attention ,please ! (请注意听) 在机场过安 ...
- 小波变换——子带编码,Subband Coding
离散小波变换.多级信号分解,多分辨率分析. Multiresolution Analysis(MRA.多分辨率分析) 子带编码(Subband Coding) 简称SBC. 一种以信号频谱为依据的编码 ...
- C++输入cin,输出cout,换行endl,getline连续读取字符
简记:cin=键盘,cout=屏幕. >>和<<指向代表数据流动方向.<<是流插入运算符,右操作数(运算符右边的值)会被插入到输出流中. 首先要包含:#includ ...
- kendo-ui下拉树形选择(DropDownTreeView)
摘要: 最近项目中有一个特殊的需求,下拉选择部门,但是部门的层级关系要在下来框中体现出来,如下图 下面我就把实现的过程分享给大家,代码如下: dropdowntreeview.js /* * * Dr ...
- [AX]AX2012 Interaction class
Ax2012 Client的form如果属性FormTemplate设置为DetailsPage或者ListPage,则必须同时设置属性InteractionClass为相应的Interaction类 ...
- mysql操作类
同事今天推荐了一个mysql链接操作的类,地址 https://github.com/joshcam/PHP-MySQLi-Database-Class 大概看了一下,还是不错的,有点意思,先记录一 ...