c++基础(六)——动态内存

  在我们的程序中,静态内存——用来保存局部 static 对象,类 static数据成员,以及定义在任何函数之外的变量。栈内存——用来保存定义在函数内的非 static 对象。分配在  静态内存 或 栈内存中的对象由编译器自动创建和销毁。对于栈内存,仅在其定义的程序块运行时才存在,static对象在使用之前分配,在程序结束时销毁。

  除此之外,每个程序还拥有一个内存池,这部分内存被称为自由空间(堆),程序用堆来存储动态分配的对象,——即那些在程序运行时分配的对象。

1. 动态内存和智能指针

  在C++中,动态内存的管理是通过一对运算符来完成的:new,在动态内存中为对象分配空间并返回一个指向该对象的指针,我们可以选择对对象进行初始化;delete,接受一个动态指针,销毁该对象,并释放与之关联的内存。

  新的标准提供了两种智能指针(smart pointer)类型来管理动态对象。shared_ptr允许多个指针指向同一个对象;unique_ptr则“独占”所指向的对象。标准库还定义了一个名为weak_ptr的伴随类,指向shared_ptr所管理的对象。这三种类型都定义在memory中。

1.1 share_ptr 类

  类似vector智能指针也是模板。

1 shared_ptr<string> p1;    //shared_ptr,可以指向string
2 shared_ptr<list<int>> p2;    //shared_ptr,可以指向int的list

  智能指针的使用方法和普通指针类似,解引用返回它指向的对象,如果在一个条件判断中使用智能指针,效果就是检测它是否为空,

1 // 如果 p1 不为空,检查它是否指向一个空 string
2 if (p1 && p1->empty()) // p->mem -- (*p).mem
3     *p1 = "ds"

1.2 make_shared 函数

  最安全的分配和使用动态内存的方法是调用一个名为make_shared的标准库函数。此函数在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr。与智能指针一样,make_shared也定义在memory中。

1 //指向一个值为42的int的shared_ptr
2 shared_ptr<int> p3 = make_shared<int>(42);
3 //p4指向一个值为”999999999”的string
4 shared_ptr<string> p4 = make_shared<string>(10,‘9‘);
5 //p5指向一个值初始化的int,即,值为0
6 shared_ptr<int> p5 = make_shared<int>();7 auto p6 = make_share<vector<string>>(); 

  

1.3 share_ptr 的拷贝和赋值

  当进行拷贝或赋值操作时,每个shared_ptr都会记录有多少个其他shared_ptr指向相同的对象:

1 auto p = make_shared<int>(42);    //p指向的对象只有p一个引用者
2 auto q(p);    //p和q指向相同对象,此对象有两个引用者

  我们可以认为每个shared_ptr都有一个关联的计数器,通常称其为引用计数(reference count)。无论何时我们拷贝一个shared_ptr,计数器都会递增;当我们给shared_ptr赋予一个新值或是shared_ptr被销毁时,计算器就会递减。
一旦一个shared_ptr的计数器变为0,它就会自动释放自己所管理的对象:

1 auto r = make_shared<int>(42);    //r指向的int只有一个引用者
2 r = q;    //给r赋值,令它指向另一个地址
3           //递增q指向的对象的引用计数
4           //递减r原来指向对象的引用计数
5           //r原来指向的对象已没有引用者,会自动释放

原文地址:https://www.cnblogs.com/KongHuZi/p/11372062.html

时间: 2024-08-07 16:08:39

c++基础(六)——动态内存的相关文章

iOS开发之c语言基础Lesson-10 动态内存管理 上课笔记 与 试题练习

//函数声明 int max(int a, int b); char * getString(); int main(int argc, const char * argv[]) { //////////////////Lesson 10 动态内存管理 课堂笔记 和 练习 ///////复习上周所学 /////////常量和变量的区别: //常量中的内容不能被修改,只能访问: //变量中存储的数据时可以随时修改的. // //const 关键字的作用: 修饰变量不可改变.当做常量使用 //  c

C和C指针小记(十六)-动态内存分配

动态内存分配 1.1 为什么使用动态内存分配 直接声明数组的方式的缺点: 1) 声明数组必须指定长度限制.无法处理超过声明长度的数组. 2) 如果声明更大的常量来弥补第一个缺点,会造成更多的内存浪费. 3)如果输入数组的数据超过来数组的容纳范围,程序必须以一种合理的方式作出响应.但是程序员一般不会做这个判断. 1.2 malloc 和 free malloc 和 free 分别用于执行动态分配内存和释放. stdlib.h 中声明来这两个函数的原型 void malloc( size_t siz

数据结构基础(1)--数组C语言实现--动态内存分配

数据结构基础(1)--数组C语言实现--动态内存分配 基本思想:数组是最常用的数据结构,在内存中连续存储,可以静态初始化(int a[2]={1,2}),可以动态初始化 malloc(). 难点就是数组在删除或者插入元素的时候,要移动元素的坐标不好确定.规律: 1.如果要在数组中第pos个位置插入一个元素(应该从后面开始移动) for( i=cnu;i>=pos;i--) pBase[i]=pBase[i-1]; 2.删除数组第pos位置的元素 for(i=pos+1;i<=cnu;i--)

C++动态内存管理好难怎么办?零基础图文讲解,小白轻松理解原理

首先我们先了解一下内存: C语言使用malloc/free动态管理内存空间,C++引入了new/delete,new[]/delete[]来动态管理内存.如果大家在自学C++中遇到困难,想找一个学习C++的环境,可以加入我的C++学习交流扣群先是513801371,能够共同学习交流和分享!![](https://s1.51cto.com/images/blog/201905/11/f3795621980960d47c291497e516b846.jpg?x-oss-process=image/w

Objective-C(十六、内存管理,自动释放池,ARC,强指针,弱指针,方法族)——iOS开发基础

结合之前的学习笔记以及参考<Objective-C编程全解(第三版)>,对Objective-C知识点进行梳理总结.知识点一直在变,只是作为参考,以苹果官方文档为准~ 十六.内存管理相关知识(二) 1.autorelease,自动释放机制 - (instancetype)autorelease; (1)自动释放池的创建 iOS5.0之前 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; //进行一系列操作 //此处不可以使用

C/C++基础----动态内存

why 管理较难,忘记释放会内存泄漏,提早释放可能非法引用,重复释放. 为了更容易,更安全的使用动态内存,提供智能指针,其默认初始化保存一个空指针. what shared_ptr允许多个指针指向同一个对象 unique_ptr独占所指向的对象 weak_ptr弱引用,指向shared_ptr所管理的对象. <memory> shared_ptr和unique_ptr都支持的操作 操作 描述 shared_ptr 空智能指针 unique_ptr 同上 p 用作条件判断 *p p->me

浅谈C++容器动态内存管理的优化

在信息学竞赛中,C++的容器的用途非常广泛,但经常因常数过大而超时.怎样才能提高它们的效率呢? 我们知道,容器是存储同一类对象的对象,既然"对象"我们无法改变,那么我们只能从"存储"入手,不难想到,不同容器在实现上的根本区别是它们对应着不同的内存组织方式,内存管理无疑是这种实现的核心,所以优化内存管理是加快容器效率的最好途径之一. 一.内存分配器简介 怎样才能优化内存管理呢?很简单,C++为我们提供了这样的接口,我们可以通过自定义容器模板中的最后一个allocato

动态内存分配类实现

今天学习了C++语言的内存动态分配,并借助所学的知识实现了一个动态内存分配类. 问题的背景为:在已经实现了一个点类的基础上,实现一个动态内存分配类,这个类 的功能为:实现根据输入的数目size,动态的生成size个点类对象:并在提供一个借口 可以对pos位置的对象进行操作:在对象生存期结束时,可以自动释放分配的内存空间. 根据描述的问题描述的需求,规划了如下的类图: 写出了一个包含三个方法的对点动态分配内存的类: 1: #ifndef _ARRAYOFPOINTS_H 2: #define _A

2015.12.14 宏定义 枚举 动态内存分配

宏定义 (#define) 宏定义的意义和用途:(习惯上,都是“k”开头) 1.为了让一些数据有意义. 2.类似于内联函数(使用简便). 3.输出日志的开关. (非零即真,0为“发布阶段”,1为“开发阶段”) 枚举 (enum) 枚举类型声明为一组相关的符号常数定义了一个类型名称.枚举用于“多项选择”场合,就是程序运行时从编译时已经设定的固定数目的“选择”中做出决定. 默认情况下,枚举中每个元素的基础类型是 int.可以使用冒号指定另一种整数值类型.默认是从0开始,后者会在前者之上+1. 动态内