码迷,mamicode.com
首页 > 编程语言 > 详细

C++ | 动态内存

时间:2020-03-25 09:15:20      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:动作   except   有一个   允许   unique   因此   分配   示例   c++   

内容

  1. 动态内存和智能指针
  2. 动态数组
  3. 使用库:文本查询程序
  4. 总结

0. 摘要

动态分配的对象(dynamically allocated objects)的生命(lifetime)独立于其被创建的地方,他们一直会存在到被明确释放(free)。

为了让使用动态分配的对象更安全,库定义了两个智能指针(smart pointer)类型来管理动态分配的对象。智能指针能确保在合适的时候自动释放其指向的对象。

  • static memory and stack memory
    • static memory:
      • for local static objects
      • for class static data members
      • for variables defined outside any function
    • stack memory
      • for nonstatic objects defined inside functions
    • automatically created and destroyed by the compiler; static objects are allocated before they are used and are destroyed when the program ends.
  • heap memory (free store)
    • for dynamically allocated objects, that is, objects that the program allocate at run time.
    • must explicitly destroy

1. 动态内存和智能指针

operators:

  • new: 分配内存,初始化对象,返回一个指向那个对象的指针;
  • delete: 销毁对象,释放内存。

动态内存难点:

  • 内存泄露(memory leak):忘记释放内存
  • 非法指针:指向被释放的内存

智能指针(C++ 11):像普通指针一样使用,并且拥有一个重要特性,可以自动删除其指向的对象。

  • shared_ptr: allows multiple pointers to refer to the same object
    • weak_ptr: a weak reference to an object managed by a shared_ptr
  • unique_ptr: owns the object to which it points

1.1 shared_ptr class

像vector一样,智能指针也是模板。因此,在创建一个智能指针时,需要提供另外的信息,也就是其指向对象的类型。

shared_prt<string> p1; // shared_ptr可以指向一个字符串

使用智能指针的方式与使用一个指针类似。去引用(dereference)一个智能指针会返回其指向的对象。

// 如果p1不是空指针,检查其指向的空字符串 if (p1 && p1->empty()) *p1 = "hi"; // 去引用并赋新值给字符串

make_shared函数

分配和使用动态内存最安全的方式是调用一个库函数,“make_shared”。

#include <memory> // for the use of ‘make_shared‘

// shared_ptr that points to an int with value 42
shared_ptr<int> p3 = make_shared<int>(42);
// p4 points to a string with value 999999999
shared_ptr<string> p4 = make_shared<string>(10, ‘9‘);
// p5 points to an int that is value initialized to 0
shared_ptr<int> p5 = make_shared<int>();

也可以使用auto来简化,

// p6 points to a dynamically allocated, empty vector<string> auto p6 = make_shared<vector<string>>();

复制和赋值给shared_ptrs

当复制或者赋值给一个 shared_ptr ,各个 shared_ptr 追踪多少个其他 shared_ptrs 指向同一个对象。

我们可以想象一个 shared_ptr 好像有一个对应的计数器,通常指代为一个 reference count 。每当我们复制一个 shared_ptr ,计数会递增一位。一旦一个 shared_ptr 的计数器归零,这个 shared_ptr 会自动释放他管理的对象。

shared_ptrs会自动销毁他们的对象

当最后一个指向某对象的 shared_ptr 被销毁,那 shared_ptr 类会自动销毁其指向的对象。这个销毁动作通过另一个特殊成员函数 destructor 来完成。

...并自动释放对应的内存

注意:如果你把 shared_ptrs 放进一个容器,并且之后需要使用其中一些但不是全部元素,记得把那些不需要的去除(erase)。

拥有动态生命周期资源的类

出于下面的目的,程序需要使用动态内存,

  1. 不知道需要多少对象;
  2. 不知道对象需要怎样的类型;
  3. 想要在许多对象间共享数据。

注意使用动态内存的一个常见原因是允许多个对象共享数据。

StrBlob类

暂略

1.2 直接管理内存

C++本身定义了两个操作符来分配和释放动态内存。“new”操作符分配内存,“delete”释放由“new”分配的内存。

使用这两个操作符去管理内存被认为是比使用智能指针更容易出错的。而且,类直接管理自己内存的话,不像那些使用智能指针的类,这些类对于成员复制、赋值和销毁类对象,不可以依赖默认的定义。结果就是,在程序中使用智能指针使编写和调试更加容易。

1.3 和 new 一起使用 shared_ptr

智能指针的构造函数(constructors)显式地(explicitly)接受指针。因此,我们不可以隐式地把一个内置指针转换为一个智能指针,我们必须使用初始化的直接形式来初始化智能指针:

shared_ptr<int> p1 = new int(1024); // error: must use direct initialization

shared_ptr<int> p2(new int(1024)); // ok: uses direct initialization

同样的,函数返回值也不可以隐式地转换为智能指针。我们必须显式地绑定一个 shared_ptr 给一个我们想返回的指针:

shared_ptr<int> clone(int p) { // ok: explicitly create a shared_ptr<int> from int* return shared_ptr<int>(new int(p)); }

不要混淆普通指针和智能指针

并且不用使用 get 来初始化或者赋值给另一个智能指针

其他 shared_ptr 操作

1.4 智能指针和异常(Exceptions)

2. 动态数组

3. 使用库:文本查询程序

4. 总结

示例程序

https://www.cnblogs.com/tenosdoit/p/3456704.html

参考

  • 《C++ Primer, Fifth Edition》, Stanley B. Lippman

C++ | 动态内存

标签:动作   except   有一个   允许   unique   因此   分配   示例   c++   

原文地址:https://www.cnblogs.com/casperwin/p/12563628.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!