Pointer Arithmetic 指针运算
C-Style Arrays
Avoid — But Know Your Enemy 避免使用c-style的数组
C-Arrays on stack
double a[3] {1.0, 1.2, 5.4};
C-Arrays on heap
auto a = make_unique<double[]>(3);
Pass C-Arrays to Function
//array 衰退(decays to)到指针,由于无法知道数组size,需要额外传递一个参数 void print (double* x, int n){ } double a[3] {1.0, 1.2, 5.4}; print(a, 3);
- copy(@beg, @end, @out)
- 为什么要避免使用C-Arrays
1.不是深拷贝/赋值
2.decays into pointers to first elementss
3.数组本身不知道它自己的size Strings in C
1.C-Arrays of characters
2.以'\0'终止每个character
3.literal “xyz” 的类型为char const[]Manual Memory Management手动内存管理
T* p = new T{args...}; //alloc object on the heap delete p; //free object //p 被叫做 owning raw pointer 原始指针
- Never 手动管理内存,除非你在实现自己的数据结构的过程中,即使这样你也应该使用std::allocator_traits来管理内存
- c++11之前的黑暗年代,大量滥用原始指针,造成很多问题,在modern c++中用智能指针,自动的delete object,不会造成内存泄漏
Valgrind
- valgrind [options] ./programe [programe options]
--help
--tool=memcheck
--lead-check=full
-v / --verbose
- valgrind [options] ./programe [programe options]
Exceptions 异常
#include <exception> //utilities for handling #include <stdexcept> //predefined rypes
- std::bad_alloc
std::bad_new_array_size
智能指针&异常安全
//使用make_unique,make_shared 而不是裸指针 //有内存泄漏风险,Widget{} void foo(unique_ptr<Widget> w, Gadget g){...} foo(new Widget{}, Gadget{}); //无内存泄漏 void foo(unique_ptr<Widget> w, Gadget g){...} foo(make_unique<Widget>(), Gadget{});
关于指针实际的使用场景,一直不是很清晰,知道看到了下面这个例子
class T3; class T2; class T1; class A { T3* m_t2;//创建和释放都由A之外的代码管理,A只负责(借用)使用;业务逻辑上保证A在使用m_t2指向的对象的时候,对象始终是存在的 shared_ptr<T2> m_t2;//由加载程序创建m_t2指向的对象,执行时,交给A来管理,涉及动态对象的管理权的交接 unique_ptr<T1> m_t1;//A管理该对象的生命周期,A的构造函数构造m_t1, A的析构函数释放m_t1; };
Allocators
- 提供内存分配策略的通用接口
Interface 接口
template<class T> class MyAllocator{ public: T* allocate(std::size_t n); void deallocate(T*, std::size_t n); }
delegate to new/delete
template<class T> class MyAllocator{ public: T* allocate(std::size_t n){ return new T[]; } void deallocate(T*, std::size_t n){ delete[] p ; } }
- 后面的讲道理没怎么搞明白,懒癌犯了再说吧
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。