Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
STL中std::vector的reserve()实现 考虑从“C++编程语言,第四版”,Bjarne Stroustrup:中的STD::vector::SaveFuffE()的实现。 template<class T, class A> void vector<T,A>::reserve(size_type newalloc) { if (newalloc<=capacity()) return; vector_base<T,A> b {vb.alloc,newalloc}; // get new storage // (see PS of question for details on vb data member) T* src = elem; // ptr to the start of old storage T* dest = b.elem; // ptr to the start of new storage T* end = elem+size(); // past-the-end ptr to old storage for (; src!=end; ++src, ++dest) { new(static_cast<void*>(dest)) T{move(*src)}; // move construct src–>~T(); // destroy } swap(vb,b); // install new base (see PS if needed) } // implicitly release old space(when b goes out of scope)_C++_C++11_Vector_Stl - Fatal编程技术网

STL中std::vector的reserve()实现 考虑从“C++编程语言,第四版”,Bjarne Stroustrup:中的STD::vector::SaveFuffE()的实现。 template<class T, class A> void vector<T,A>::reserve(size_type newalloc) { if (newalloc<=capacity()) return; vector_base<T,A> b {vb.alloc,newalloc}; // get new storage // (see PS of question for details on vb data member) T* src = elem; // ptr to the start of old storage T* dest = b.elem; // ptr to the start of new storage T* end = elem+size(); // past-the-end ptr to old storage for (; src!=end; ++src, ++dest) { new(static_cast<void*>(dest)) T{move(*src)}; // move construct src–>~T(); // destroy } swap(vb,b); // install new base (see PS if needed) } // implicitly release old space(when b goes out of scope)

STL中std::vector的reserve()实现 考虑从“C++编程语言,第四版”,Bjarne Stroustrup:中的STD::vector::SaveFuffE()的实现。 template<class T, class A> void vector<T,A>::reserve(size_type newalloc) { if (newalloc<=capacity()) return; vector_base<T,A> b {vb.alloc,newalloc}; // get new storage // (see PS of question for details on vb data member) T* src = elem; // ptr to the start of old storage T* dest = b.elem; // ptr to the start of new storage T* end = elem+size(); // past-the-end ptr to old storage for (; src!=end; ++src, ++dest) { new(static_cast<void*>(dest)) T{move(*src)}; // move construct src–>~T(); // destroy } swap(vb,b); // install new base (see PS if needed) } // implicitly release old space(when b goes out of scope),c++,c++11,vector,stl,C++,C++11,Vector,Stl,这可能会失败: memcpy() 对于所有其他类型的对象,它都会失败,因为它不尊重它复制的对象的语义(复制构造) 问题的例子: 如果对象的构造函数将一些内部指针设置为内部成员,则memcpy()将复制原始指针的值,该值将不会正确更新,并继续指向将释放的内存区域 如果对象包含共享\u ptr,则对象计数将变得不一致(memcpy()将复制指针而不增加其引用计数,然后swap()将确保原始共享指针位于b中,b将被释放,因此共享指针引用计数将递减) 正如T.C在评论中指出的,一旦向量存储了非P

这可能会失败:

  • memcpy()

  • 对于所有其他类型的对象,它都会失败,因为它不尊重它复制的对象的语义(复制构造)

问题的例子:

  • 如果对象的构造函数将一些内部指针设置为内部成员,则
    memcpy()
    将复制原始指针的值,该值将不会正确更新,并继续指向将释放的内存区域
  • 如果对象包含
    共享\u ptr
    ,则对象计数将变得不一致(
    memcpy()
    将复制指针而不增加其引用计数,然后
    swap()
    将确保原始共享指针位于b中,b将被释放,因此共享指针引用计数将递减)

正如T.C在评论中指出的,一旦向量存储了非POD数据,
memcpy()
就会导致UB(未定义的行为).

若元素保留一个指向自己的指针,或者依赖于自己的地址,这将失败。若元素复制了这个指针,或者将这个指针复制到lambda或类似的东西,这就足够了。@AaronI这个建议是UB,简单明了,所以知道得更好的Bjarne和co为什么不使用它。尽管如此…任何可以使用指向自身的指针的元素都是一个对象,因此它不需要存储自己的地址,因为它总是可以在方法中使用
this
来访问它。而且因为
this
指针在概念上并不存在-它是在调用方法的任何对象时生成的-它不能成为wrong.这只是UB,句号,用于非平凡的可复制类型。目的地没有活体。@T.C.当然是UB!但是我认为值得尝试向
memcpy
瘾君子解释,并且用
memcpy
参数解释一个对象超过了它的记忆总和;-)当然,但值得强调的是它在一般情况下,UB的实现可以让您的cat怀孕,即使问题的类是
struct A{~A(){};
.UB==Undefined Behavior.POD太强了,顺便说一句。您只需要少量的可复制性。
template<class T, class A>
void vector<T,A>::reserve(size_type newalloc)
{
    if (newalloc<=capacity()) return;
    vector_base<T,A> b {vb.alloc,newalloc};    // get new space

    memcpy(b.elem, elem, sz);                  // copy raw memory
                                               // (no calls to ctors or dtors)

    swap(vb,b);                                // install new base
} // implicitly release old space(when b goes out of scope)
// used as a data member in std::vector
template<class T, class A = allocator<T> >
struct vector_base {                    // memory structure for vector
     A alloc;       // allocator
     T* elem;       // start of allocation
     T* space;      // end of element sequence, start of space allocated for possible expansion
     T* last;       // end of allocated space

     vector_base(const A& a, typename A::size_type n)
         : alloc{a}, elem{alloc.allocate(n)}, space{elem+n}, last{elem+n} { }
     ~vector_base() { alloc.deallocate(elem,last–elem); } // releases storage only, no calls 
                                                          // to dtors: vector's responsibility        
     //...
};

// std::vector
template<class T, class A = allocator<T> >
class vector {
     vector_base<T,A> vb;            // the data is here
     void destroy_elements();
public:
     //...
};