c++内存管理学习(c++ Primer)

一:动态内存管理

allocator类:

请添加图片描述

/* 拷贝元素 */
void StrVer::push_back(const string& s) {
    chk_n_alloc();  //确保有空间容纳新元素
    alloc.construct(first_free++,s);    //拷贝元素并指向下一个地址
}
/* 内存释放 */
void StrVer::free() {
    if (elements) { //如果没有分配空间则不执行(首地址无指针)
        for (auto p = first_free; p != elements; --p) { //从空闲的第一个到首地址
            alloc.destroy(p);     //销毁元素
        }
        alloc.deallocate(begin(), size());    //释放空间
    }
}

allocator算法请添加图片描述

/* 内存分配 */
pair<string*, string*> 
StrVer::alloc_n_copy(const string* b, const string* e) {
    string* data = alloc.allocate(e - b);  //分配能容纳给定元素的空间(返回首地址)
    return { data,uninitialized_copy(b,e,data) };   //返回一个pair(首地址,尾地址)
}


整体代码示例:

class StrVer {
public:
    StrVer() :first_free(nullptr), elements(nullptr), cap(nullptr) {};
    StrVer(const StrVer&);
    StrVer& operator==(const StrVer&);
    ~StrVer() { free(); };
    void push_back(const string&);   //拷贝元素
    size_t size() const { return first_free - elements; };//空间总大小
    size_t capacity() const { return cap - elements; }; //所用空间
    string* begin() const { return elements; }; //头指针
    string* end() const { return first_free; }; //尾指针
private:
    allocator<string> alloc;   // 被添加的元素所使用(这里测试后不能加static不知道为什么)
    
    void chk_n_alloc() {    //保证至少有一个容纳新元素的空间
        if (size() == capacity()) reallocate();
    }
    pair<string*, string*> alloc_n_copy(const string*,const string*);   //内存分配
    void free();            //销毁元素并释放内存
    void reallocate();      //获得跟多内存拷贝已有元素
    string* elements;       //元素首地址
    string* first_free;     //元素第一个空闲指针
    string* cap;            //元素尾地址
};
/* 拷贝元素 */
void StrVer::push_back(const string& s) {
    chk_n_alloc();  //确保有空间容纳新元素
    alloc.construct(first_free++,s);    //拷贝元素并指向下一个地址
}
/* 内存分配 */
pair<string*, string*> 
StrVer::alloc_n_copy(const string* b, const string* e) {
    string* data = alloc.allocate(e - b);  //分配能容纳给定元素的空间(返回首地址)
    return { data,uninitialized_copy(b,e,data) };   //返回一个pair(首地址,尾地址)
}
/* 内存释放 */
void StrVer::free() {
    if (elements) { //如果没有分配空间则不执行(首地址无指针)
        for (auto p = first_free; p != elements; --p) { //从空闲的第一个到首地址
            alloc.destroy(p);     //销毁元素
        }
        alloc.deallocate(begin(), size());    //释放空间
    }
}
/* 拷贝构造函数 */
StrVer::StrVer(const StrVer& s) {
    pair<string*, string*> newdata = alloc_n_copy(s.begin(), s.end());    //分配同样多的内存空间
    elements = newdata.first;   //首地址
    first_free = cap = newdata.second;  //尾地址和当前地址
};
/* 重载赋值 */
StrVer& StrVer::operator==(const StrVer& rhs) {
    free(); //释放当前内存
    pair<string*, string*> newdata = alloc_n_copy(s.begin(), s.end());    //分配同样多的内存空间
    elements = newdata.first;   //首地址
    first_free = cap = newdata.second;  //尾地址和当前地址
    return *this;
}
/* 获得跟多内存拷贝已有元素 */
void StrVer::reallocate(){
    size_t newcapacity = size() ? 2 * size() : 1; //双倍空间或者申请空间
    string* newdata = alloc.allocate(newcapacity); //申请新空间
    string* dest = newdata;    //新空间首地址
    string* elem = elements;   //旧空间首地址
    for (size_t i = 0; i != size(); i++) {
        alloc.construct(dest++, std::move(*elem++));    //拷贝
    }
    free(); //释放就内存
    /* 更新数据 */
    elements = newdata;
    first_free = dest;
    cap = newdata + newcapacity;
}




二: 对象移动与左右值

/* 移动构造 */
/* 移动构造 */
StrVer::StrVer(StrVer&& rhs) noexcept {
    free();
    elements = rhs.elements;
    first_free = rhs.first_free;
    cap = rhs.cap;
    rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
/* 移动赋值 */
StrVer& StrVer::operator=(StrVer&& rhs) noexcept {
    if (this != &rhs) {
        free();
        elements = rhs.elements;
        first_free = rhs.first_free;
        cap = rhs.cap;
        rhs.elements = rhs.first_free = rhs.cap = nullptr;
    }
    return* this;
}

在主程序中使用:

int main()
{
    StrVer p1,p2,p3;
    p1.push_back("123456"); //写入数据
    p2 = p1;    //调用拷贝赋值函数
    p3 = move(p2);  //调用移动赋值函数
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值