allocator 分配内存和释放有关问题导致程序崩溃

allocator 分配内存和释放问题导致程序崩溃
最近学到c++primer第十三章,编写StrVec类,跟vector类比。我按照书本实现了,代码应该差不多,但是在执行程序的时候,程序会在最后结束时,调用destructor时崩溃,我只能用IDE追踪到这里,还是不能解决问题,不知道大神能不能帮我看看问题。
编译环境:visual studio 2015

Exercise13.39.cpp:
#include"Exercise13_39.h"

int main() 
{
StrVec stringVb, stringVa;
stringVa.push_back("hello world!");
stringVa.push_back("hello xiaoming");

//stringVa = stringVb;

for (auto p = stringVa.begin(); p != stringVa.end(); ++p)
{
cout << *p << endl;
}

}


Exercise13_39.h:
#ifndef Exercise13_39_h_
#define Exercise13_39_h_

#include<iostream>
using std::cout;
using std::cin;
using std::endl;
using std::pair;
#include<string>
using std::string;
#include<memory>
using std::allocator;
class StrVec 
{
private:
allocator<string> alloc;
string * elements; // point the the first element in StrVec;
string * first_free; ; // point to the first free space, that is
// the end of elements 
string * cap; // point to the end of the space allocated
void free(); // free the space allocated
void reallocate(); // free space reallocate space to store elements
void check_n_alloc() { if (size() == capacity()) reallocate(); }; // if need to allocate, do it
// utilities used by copy constructor, assigment operator and destructor
pair<string *, string *> alloc_n_copy(const string *, const string *);
public:
StrVec(): elements(nullptr), first_free(nullptr), cap(nullptr) // default constructor
{}
StrVec(const StrVec&); // copy constructor
StrVec& operator=(const StrVec&); // copy  assigment
~StrVec(); // destructor
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; }
};

#endif


Exercise13_39.cpp:
#include"Exercise13_39.h"

void StrVec::free() 
{
if (elements) 
{
// from back to front, destroy the elements which are constructed
for (auto ptr = first_free; ptr != elements;)
{
alloc.destroy(--ptr); // use string destructor to destroy  element
}
// deallocate the space which allocator allocate
alloc.deallocate(elements, cap - elements); 
}
}

void StrVec::reallocate() 
{
// we allocate space twice as many elements as the current size
auto newCapacity = size() > 1 ? 2 * size() : 1;
// allocate new space
auto newData = alloc.allocate(newCapacity);
auto dest = newData; // a pointer that point to newData
auto elem = elements; // pointer that point to the old data
for (size_t i = 0; i < size(); ++i)
{
alloc.construct(dest++, std::move(*elem++));
}
free(); // free the old space
// set pointer point to the new space
elements = newData;
first_free = dest;
cap = elements + newCapacity;
}

pair<string *, string *> StrVec::alloc_n_copy(const string * b, const string * e) 
{
// allocate space to hold as many elements as are in the range
auto data = alloc.allocate(e - b);
return{data, uninitialized_copy(b, e, data)};
}

StrVec::StrVec(const StrVec& orig) 
{
// call alloc_n_copy to allocate space and copy data
auto newData = alloc_n_copy(orig.begin(), orig.end());
// update pointers
elements = newData.first;
first_free = cap = newData.second;
}

StrVec& StrVec::operator=(const StrVec& rhs) 
{
// call alloc_n_copy to allocate space and copy data
auto newData = alloc_n_copy(rhs.begin(), rhs.end());
// first, free the old memory
free();
//update pointers
elements = newData.first;
first_free = cap = newData.second;
return *this;
}

StrVec::~StrVec() 
{
// only need to free the memory allocated
free();
}

void StrVec::push_back(const string & str) 
{
check_n_alloc();
alloc.construct(first_free++, str);
}


------解决思路----------------------
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。

------解决思路----------------------
auto newCapacity = size() >= 1 ? 2 * size() : 1;
否则当size() == 1时永远不能分配更大的内存