void str_vec::reallocate()
{
    auto new_capacity = size()>1?size()*2:1;
    auto new_data = alloc.allocate(new_capacity);
    auto dest = new_data;
    auto elem = elements;
    for(std::size_t i = 0;i<size();++i)
        alloc.construct(dest++,std::move(*elem++));
    free();
    elements = new_data;
    first_free = dest;
    std::cout << cap - elements << std::endl;
    cap = new_data+new_capacity;
}
/**
* @brief   allocate memory for spicified number of elements
* @param n
* @note    it's user's responsibility to ensure that @param n is greater than
*          the current capacity.
*/
void StrVec::wy_alloc_n_move(std::size_t n)
{
	std::size_t newCapacity = n;

	std::string*
		newData = alloc.allocate(newCapacity);

	std::string*
		dest = newData;
	std::string*
		elem = element;

	//! move the old to newly allocated space.
	for (std::size_t i = 0; i != size(); ++i)
		alloc.construct(dest++, std::move(*elem++));

	free();

	//! update data structure
	element = newData;
	first_free = dest;
	cap = element + newCapacity;
}
/**
* @brief   allocate new room if nessary and push back the new string
* @param s new string
*/
void StrVec::push_back(const std::string& s)
{
	chk_n_alloc();
	alloc.construct(first_free++, s);
}
Beispiel #4
0
        void reallocate()
        {
            auto newcap = size() ? size()*2 : 1;

            auto newspace = alloc.allocate(newcap);

            std::cout << "reallocate: size() " << size() << std::endl;

            auto dest = newspace;
            auto source = element_;

            // move the data from the old memory to the new
            // std::move() returns rvalue, which cause construct() to use string
            // move ctor.
            //
            // seg-fault when have a typo and use element in the loop:
            //
            // for (size_t i = 0; i != size(); ++i)
            //     alloc.construct(dest++, std::move(*element_++));
            //
            // *gdb-debug* bt when use -g
            // Program terminated with signal SIGSEGV, Segmentation fault.
            // #0  0x00007f94aa120113 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string&&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
            // (gdb) bt
            // #0  0x00007f94aa120113 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string&&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
            // #1  0x0000000000401bf7 in __gnu_cxx::new_allocator<std::string>::construct<std::string<std::string> > (this=0x602cd1 <StrVec::alloc>, __p=0xa53000) at /usr/include/c++/4.9/ext/new_allocator.h:120
            // #2  0x0000000000401932 in StrVec::reallocate (this=0x7ffdc9026bc0) at t_ex_strvec.cpp:117
            // #3  0x0000000000401aa5 in StrVec::check_and_alloc (this=0x7ffdc9026bc0) at t_ex_strvec.cpp:147
            // #4  0x000000000040165e in StrVec::push_back (this=0x7ffdc9026bc0, s="two") at t_ex_strvec.cpp:44
            // #5  0x000000000040133e in main () at t_ex_strvec.cpp:198
            //
            // when not use -g
            // (gdb) bt
            // #0  0x00007f3348f5c113 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string&&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
            // #1  0x0000000000401bf7 in void __gnu_cxx::new_allocator<std::string>::construct<std::string, std::string>(std::string*, std::string&&) ()
            // #2  0x0000000000401932 in StrVec::reallocate() ()
            // #3  0x0000000000401aa5 in StrVec::check_and_alloc() ()
            // #4  0x000000000040165e in StrVec::push_back(std::string const&) ()
            // #5  0x000000000040133e in main ()
            //
            // How to debug? See that uses 'construct' and gdb is useful to see
            // what's going on when stepping through. Found out that the loop
            // continues and saw that when add to print i and size().
            //
            // ...
            // i: 16856, size: 18446744073709534761
            // Segmentation fault (core dumped)
            //
            // (gdb) f 2
            // #2  0x0000000000401932 in StrVec::reallocate (this=0x7ffdc9026bc0) at t_ex_strvec.cpp:117
            // 117                     alloc.construct(dest++, std::move(*element_++));
            // (gdb) p i
            // $1 = 16856
            // (gdb) p/u free_-element_
            // $6 = 18446744073709534760
            //
            // Why? Since element_ is member data and keep increasing it, then
            // size() member function would produce negative which turns into
            // big number sicne size() returns size_t, unsigned int.

            for (size_t i = 0; i != size(); ++i)
            {
                // std::cout << "i: " << i << ", size: " << size() << std::endl;
                alloc.construct(dest++, std::move(*source++));
            }

            // std::cout.flush();
            // std::this_thread::sleep_for(std::chrono::seconds{5});

            // to point the new space
            element_ = newspace;
            free_ = dest;
            cap_ = element_ + newcap;
        }