20200220
Plan
60min: CPP smart pointer
Notes
- shared_ptr 和 unique_ptr 都无法进行赋值,weak_ptr 需要从 shared_ptr 构建。
- shared_ptr 可以指定 deleter,尤其 share_ptr 从一个栈指针构建出来的时候,必须指定 deleter,否则就会对栈指针做 delete 操作,而这个是非法的。
- allocator 可以做 allocate/deallocte、construct/destory 这两对操作,事实证明,delete ptr 是两步操作,调用 ptr 指向的类对象的析构函数,然后(destroy),然后回收相应的内存(deallocate)。
- unique_ptr 类似 rust 里面的最普通的 Box 指针,只有一个 owner。
练习:
#include <iostream>
#include <memory>
#include <vector>
struct Obj {
int i_;
Obj(int i) : i_(i) {}
~Obj() { std::cout << "obj is freed, i=" << i_ << std::endl; }
};
void test_auto_new() {
Obj obj(1);
auto s = new auto(obj);
delete s;
}
void test_delete_share_ptr_get() {
auto sp = std::make_shared<int>();
auto p = sp.get();
// p can not be deleted otherwise double free will occur
// delete p;
}
void test_delete() {
Obj obj(3);
// next line will cause &obj is deleted but the pointer
// is never allocated before.
// std::shared_ptr<Obj> p(&obj);
std::shared_ptr<Obj> p(
&obj, [](Obj *obj) { std::cout << "obj is custom freed" << std::endl; });
}
void test_unique_init() { std::unique_ptr<Obj> u(new Obj(4)); }
void test_alloc() {
std::allocator<int> alloc;
std::vector<int> vi = {1, 2, 3};
auto p = alloc.allocate(vi.size() * 2);
auto q = std::uninitialized_copy(vi.begin(), vi.end(), p);
std::uninitialized_fill_n(q, vi.size(), 10);
for (auto it = p; it != (p + vi.size() * 2); it++) {
std::cout << *it << ", ";
}
std::cout << std::endl;
}
void test_alloc_destroy() {
std::allocator<Obj> alloc;
auto p = alloc.allocate(2);
alloc.construct(p, 5);
alloc.destroy(p);
p->i_ = 6;
alloc.destroy(p);
alloc.deallocate(p, 2);
}
int main() {
test_auto_new();
test_delete_share_ptr_get();
test_delete();
test_unique_init();
test_alloc();
test_alloc_destroy();
return 1;
}
More
- std::initializer_list