【c++】动态内存
静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。注意:const常量在定义时必须初始化
栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放,栈区由系统自动分配。
堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。
shared_ptr类
shared_ptr初始化:使用make_shared<T>(args)函数
shared_ptr<int> p=make_shared<int>(42);
auto p=make_shared<string>();
每个shared_ptr都有一个关联的计数器(引用计数)即多少个指针指向shared_ptr管理的变量,无论何时我们拷贝一个shared_ptr,计数都会递增。当我们给shared_ptr赋予一个新值或是shared_ptr被销毁时,计数器就会递减。一旦一个shared_ptr的计数器变为0,就会自动释放自己管理的对象。
auto p=make_ptr<int>(42);//p指向的对象只有一个引用者
auto q(p);//p和q指向相同对象,此对象有两个引用者
auto r=make_shared<int>(42);
r=q;//r原来指向的对象已没有引用者,会自动释放
总结:智能指针类能记录有多少shared_ptr指向相同的对象,并能在恰当的时候自动释放对象。
直接管理内存
动态分配的对象是默认初始化的,这意味着内置类型或组合类型的对象的值是未定义的,而类类型对象将用默认构造函数进行初始化
string *ps=new string;//初始化为空string
int *pi=new int;//pi指向一个未初始化的int
传统的构造方式(圆括号):
int *pi=new int(1024);
我们传递给delete的指针必须指向动态分配的内存,或者是空指针,释放一块不是new分配的内存,或者将相同的指针释放多次,其行为是未定义的。
shared_ptr与new结合使用
我们不能将一个内置指针隐式转换为一个智能指针,必须使用直接初始化形式来初始化一个智能指针。
shared_ptr<int>p = new int(1024);//错误
shared_ptr<int>q(new int(1024));//正确
class shared //一个拥有shared_ptr的类
{
private:
shared_ptr<int> p; //shared_ptr成员变量
public:
shared(shared_ptr<int> p_) :p(p_){} //构造函数初始化shared_ptr
void print() //输出shared_ptr的引用计数和指向的值
{
cout << "count:" << p.use_count()
<< "v =" << *p << endl;
}
};
void print_func(shared_ptr<int> p) //使用shared_ptr作为函数参数
{
//同样输出shared_ptr的引用计数和指向的值
cout << "count:" << p.use_count()
<< " v=" << *p << endl;
}
int main()
{
shared_ptr<int> p(new int());
shared s1(p), s2(p); //构造两个自定义类
s1.print();
s2.print();
*p = ; //修改shared_ptr所指的值
print_func(p);
s1.print();
system("pause");
}
/*输出为
count:3v =100
count:3v =100
count:4 v=20
count:3v =20
*/
在声明了shared_ptr和两个shared实例后,指针被它们所共享,因此引用计数为3.printf_func函数内部拷贝了一个shared_ptr对象,因此引用计数再增加1,但当退出函数时拷贝自动析构,引用计数又恢复3。
【c++】动态内存的更多相关文章
- 【转】Linux C动态内存泄漏追踪方法
原文:http://www.cnblogs.com/san-fu-su/p/5737984.html C里面没有垃圾回收机制,有时候你申请了动态内存却忘记释放,这就尴尬了(你的程序扮演了强盗角色,有借 ...
- C++指针和动态内存分配
指针和动态内存分配 数组与指针 数组 数组名是一个指针常量. 数组名传递数据时,传递的是地址. 数组作为函数参数时不指定第一维大小. 对象数组 A a[2] = {A(1,2)}; 执行时先调用有参数 ...
- SQLite剖析之动态内存分配
SQLite通过动态内存分配来获取各种对象(例如数据库连接和SQL预处理语句)所需内存.建立数据库文件的内存Cache.保存查询结果. 1.特性 SQLite内核和它的内存分配子系统提供以下特性 ...
- C和指针 第十一章 动态内存分配
声明数组时,必须指定数组长度,才可以编译,但是如果需要在运行时,指定数组的长度的话,那么就需要动态的分配内存. C函数库stdlib.h提供了两个函数,malloc和free,分别用于执行动态内存分配 ...
- 解决Ubuntu Server 12.04 在Hyper-v 2012 R2中不能使用动态内存的问题
前言 全新Hyper-v 2012 R2终于开始支持在Linux的VPS中使用动态内存,可以大大优化服务器的资源分配,小弟我兴奋不已,于是抽空时间赶紧升级到 2012 R2,好好整理一番内存分配,不过 ...
- 动态内存分配导致Javascript性能的问题
内存分配对性能的影响是很大的,分配内存本身需要时间,垃圾回收器回收内存也需要时间,所以应该尽量避免在堆里分配内存.不过直到最近优化HoLa cantk时,我才深刻的体会到内存分配对性能的影响,其中有一 ...
- C++动态内存管理之shared_ptr、unique_ptr
C++中的动态内存管理是通过new和delete两个操作符来完成的.new操作符,为对象分配内存并调用对象所属类的构造函数,返回一个指向该对象的指针.delete调用时,销毁对象,并释放对象所在的内存 ...
- 【C++】动态内存与智能指针
C++常见的内存分配方式有三种: 从静态存储区分配,这里主要是存储局部static对象,类的static成员以及定义在函数之外的变量: 从栈内存分配,这里主要是存储函数内的非static对象: 从堆内 ...
- C++动态内存分配
C++动态内存分配1.堆内存分配 :C/C++定义了4个内存区间:代码区,全局变量与静态变量区,局部变量区即栈区,动态存储区,即堆(heap)区或自由存储区(free store). 堆的概念:通常定 ...
- C++——类和动态内存分配
一.动态内存和类 1.静态类成员 (1)静态类成员的特点 无论创建多少对象,程序都只创建一个静态类变量副本.也就是说,类的所有对象都共享同一个静态成员. (2)初始化静态成员变量 1)不能在类声明中初 ...
随机推荐
- vscode 打开新文件不替换旧文件
设置 "workbench.editor.enablePreview": false
- 在CNN网络中roi从原图映射到feature map中的计算方法
在使用fast rcnn以及faster rcnn做检测任务的时候,涉及到从图像的roi区域到feature map中roi的映射,然后再进行roi_pooling之类的操作.比如图像的大小是(600 ...
- 跑RFCN
按照这个来http://blog.csdn.net/sinat_30071459/article/details/53202977
- 暑假集训 || LCA && RMQ
LCA定义为对于一颗树 树上两个点的最近公共祖先 一.Tarjan求LCA(离线方法 https://blog.csdn.net/lw277232240/article/details/7701751 ...
- js模块化入门与commonjs解析与应用
JS模块化的基本原理 commonjs规范 commonjs在前端模块化中的基本使用 AMD与CMD规范剖析博客链接 一.JS模块化基本原理 在JS没有提出来模块化的时候,开发JS项目比较简单,同时也 ...
- composer 设置代理
在命令行终端中输入以下内容: export https_proxy='192.168.1.133:1080' export http_proxy='192.168.1.133:1080' 此前提是你已 ...
- 计算机网络之TCP拥塞控制
1. 首先,拥塞控制和流量控制是不一样的. 拥塞控制是防止过多的数据注入到网络中,可以使网络中的路由器或链路不致过载,是一个全局性的过程. 流量控制是点对点通信量的控制,是一个端到端的问题,主要就是 ...
- Django框架基础知识13-auth系统
我们昨天登录admin时创建的用户信息是存放在哪里了呢? auth系统的数据表: 从表的名称我们就能看出, auth_user,auth_group,auth_permission分别存放了用户,用户 ...
- cherrypy & gevent patch
给cherrypy 打gevent WSGIServer的patch 1. patch Serving 类 2. 关闭python的原生WSGIServer 具体使用例子参考 我的开源项目 http ...
- jenkins 提示No emails were triggered
发送邮件 Jenkins->系统管理->系统设置,在“邮件通知”里设置smtp服务器地址,以及发送者邮箱地址,在具体的任务构建完成以后,可以设置发送邮件,在某一个任务的"Add ...