zoukankan      html  css  js  c++  java
  • insert和delete底层实现的方式

    operator delete ()全局函数原型:

    /*
    operator delete: 该函数最终是通过free来释放空间的
    */
    void operator delete(void *pUserData)
    {
    _CrtMemBlockHeader * pHead;

    RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));

    if (pUserData == NULL)
    return;

    _mlock(_HEAP_LOCK); /* block other threads */
    __TRY
    /* get a pointer to memory block header */
    pHead = pHdr(pUserData);

    /* verify block type */
    _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

    _free_dbg( pUserData, pHead->nBlockUse );

    __FINALLY
    _munlock(_HEAP_LOCK); /* release other threads */
    __END_TRY_FINALLY

    return;
    }
    /*
    free的实现
    */
    #define free(p) _free_dbg(p, _NORMAL_BLOCK)

    delete的原理:

    1. 在空间上执行析构函数,完成对象中资源的清理工作;
    2. 调用operator delete函数释放对象的空间;

    insert函数缺点:
    不能正确实现原vector尾部的插入,其他都可以。
    原vector尾部的插入,结果如下:
    每次都是在原vector的固定末尾位置插入新元素,并将之前插入的元素向后挪了挪。

    insert 函数

    //插入 在值为value的一个元素到position的位置上
    void insert(iterator position, const T& value){
    insert(position, 1, value);
    }

    //在position位置之后,插入n的值为value的元素
    void insert(iterator position, size_type n, const T& value){
    if (n == 0)return;

    if ((end_of_storage - finish) >= n){//备用空间够插入n个新元素
    T x_copy = value;
    const size_type size_from_position_to_end = finish - position;

    iterator old_finish = finish;
    if (size_from_position_to_end > n){
    __copy(finish - n, finish, finish);
    finish += n;
    __backCopy(position, old_finish - n, old_finish);
    __fill(position, position + n, x_copy);
    }
    else{
    __fill_n(finish, n - size_from_position_to_end, x_copy);
    finish += n - size_from_position_to_end;
    __copy(position, old_finish, finish);
    finish += size_from_position_to_end;
    __fill(position, old_finish, x_copy);
    }
    }
    else{
    //重新申请空间
    const size_type old_size = size();
    size_type _max = 0;
    if (old_size > n) _max = old_size;
    else _max = n;
    const size_type len = old_size + _max;
    iterator new_start = (iterator)malloc(len * sizeof(T));
    iterator new_finish = new_start;
    //内存的分配要有原子性,即:要么全部成功,要么全部失败。
    try{
    new_finish = __copy(begin(), position, new_start);//1.将原内容 至position的所有元素(不包含position) 拷贝到新的vector
    new_finish = __fill_n(new_finish, n, value);//2.将position位置到后面的n个元素都填充为value
    new_finish = __copy(position, end(), new_finish);//3.拷贝从 position位置到end()位置的原vector的所有剩余元素
    }
    catch (...)//如果失败了
    {
    destroy(new_start, new_finish);
    free(new_start);//删除申请到的内存
    new_start = new_finish = NULL;
    throw; //抛出异常
    }
    //析构并释放原vector
    destroy(begin(), end());
    //删除内存
    free(start);
    //调整迭代器,指向新的vector
    start = new_start;
    finish = new_finish;
    end_of_storage = new_start + len;
    }
    }
    insert 中调用的一些子函数:

    //将first到last迭代器之间(first,last)的元素拷贝到_start开始的内存中, 并返回 指向 拷贝完所有数据之后最后一个数据的下一个位置的指针
    iterator __copy(iterator first, iterator last, iterator _start){
    while (first < last){
    *_start++ = *first++;
    }
    return _start;
    }

    iterator __fill(iterator first, iterator last, const T& value){
    while (first < last){
    *first++ = value;
    }
    return first;
    }

    //自己写的 从迭代器first开始填充n个值为value的元素
    iterator __fill_n(iterator first, size_type n, const T& value){
    while (n--){
    *first++ = value;
    }
    return first;
    }


    //自己写的 将从 [first,last)所有元素 一一依次后移, 最后的一个元素移到end的位置
    void __backCopy(iterator first, iterator last, iterator end){
    while (first <= last){
    *end-- = *last--;
    }
    }

  • 相关阅读:
    8.10
    今日头条笔试题 1~n的每个数,按字典序排完序后,第m个数是什么?
    Gym 100500B Conference Room(最小表示法,哈希)
    CodeForces 438D The Child and Sequence(线段树)
    UVALIVE 6905 Two Yachts(最小费用最大流)
    Gym Conference Room (最小表示法,哈希)
    hdu 2389 Rain on your Parade(二分图HK算法)
    Codeforces Fox And Dinner(最大流)
    zoj 3367 Counterfeit Money(dp)
    ZOJ3370. Radio Waves(2-sat)
  • 原文地址:https://www.cnblogs.com/danxun/p/11604231.html
Copyright © 2011-2022 走看看