所以我有一个定制的矢量类,还有一个自定义分配器:
#define _SCL_SECURE_NO_WARNINGS
#include <iostream>
#include <exception>
#include <sstream>
#include <string>
#include <iostream>
namespace mem {
template<typename T>
class allocator {
public:
//
T * allocate(int n); //allocate space for n objects of type T
void deallocate(T* p); //deallocate n objects of type T starting at p
void construct(T* p, const T& v); // construct a T with the value v in p
void destroy(T* p); // destroy the T in p
};
template<typename T> T* allocator<T>::allocate(int n) //allocate space for n objects of type T
{
T* res = (T*)malloc(sizeof(T)*n);
if (res == nullptr)
throw std::bad_alloc();
return res;
}
template<typename T> void allocator<T>::deallocate(T* p/*, int n*/) //deallocate n objects of type T starting at p
{
free(p);
}
template<typename T> void allocator<T>::construct(T* p, const T& v) // construct a T with the value v in p
{
new(p) T(v);
}
template<typename T> void allocator<T>::destroy(T* p) // destroy the T in p
{
p->~T();
}
}
namespace vec {
template<typename T, typename A = mem::allocator<T>>
class vector {
A alloc; //use allocate to handle memory for elements
int sz; //the size
T* elem; //a pointer to the elements
int space; //size + free space
public:
using size_type = unsigned long;
using value_type = T;
using iterator = T * ;
using const_iterator = const T*;
vector() :sz{ 0 }, elem{ nullptr }, space{ 0 } {}
explicit vector(int s) :sz{ s }, elem{ new T[s] }, space{ s }
{
for (int i = 0; i < sz; ++i) elem[i] = 0; // elements are initalized
}
vector(const vector& arg); //copy constructor
vector& operator =(const vector& a); //copy assignment
vector(vector&& a); //move constructor
vector& operator=(vector&& a); //move assignment
~vector() { delete[] elem; } //destructor
void reserve(int newalloc);
void resize(int newsize, T val = T()); //growth
void push_back(const T& val);
iterator begin() { return elem; }
const_iterator begin()const { return elem; }
iterator end() { return elem + sz; }
const_iterator end() const { return elem + sz; }
size_type size() { return sz; }
iterator back() { return end() - 1; }
const_iterator back() const { return end() - 1; }
};
template<typename T, typename A> vector<T, A>::vector(const vector<T, A>& a) //copy constructor
:sz{ a.sz }, elem{ new T[a.sz] }
{
copy(a.elem, a.elem + sz, elem);
}
template<typename T, typename A> vector<T, A>& vector<T, A>::operator =(const vector<T, A>& a) //copy assignment
{
if (this == &a) return *this; //return if self assignment
if (a.sz <= space) { //enough space no need for new allocation
for (int i = 0; i < a.sz; ++i) //copy elements
alloc.construct(&elem[i], a.elem[i]);
sz = a.sz;
return *this;
}
T* p = alloc.allocate(a.sz);//allocate new size
for (int i = 0; i < a.sz; ++i) //copy elements
alloc.construct(&p[i], a.elem[i]);
for (int i = 0; i < sz; ++i)
alloc.destroy(&elem[i]); //destroy
alloc.deallocate(elem);
space = sz = a.sz; //set new size
elem = p; //set new elements
return *this; //return a self reference
}
template<typename T, typename A> vector<T, A>::vector(vector<T, A>&& a) //move constructor
:sz{ a.sz }, elem{ a.elem }
{
a.sz = 0; //make a the empty vector
a.elem = nullptr;
}
template<typename T, typename A> vector<T, A>& vector<T, A>::operator=(vector<T, A>&& a) //move assignment
{
delete[] elem; //deallocate old space
elem = a.elem; //copy a's elem and sz
sz = a.sz;
a.elem = nullptr; //make a the empty vector
a.sz = 0;
return *this;
}
template<typename T, typename A> void vector<T, A>::reserve(int newalloc)
{
if (newalloc <= space) return; //never decrease allocation
T* p = alloc.allocate(newalloc); //alocate new space
for (int i = 0; i < sz; ++i)
alloc.construct(&p[i], elem[i]); //copy
for (int i = 0; i < sz; ++i)
alloc.destroy(&elem[i]); //destroy
alloc.deallocate(elem/*, space*/); //deallocate old space
elem = p;
space = newalloc;
}
template<typename T, typename A> void vector<T, A>::push_back(const T& val)
{
if (space == 0)
reserve(8);
else if (space == sz)
reserve(2 * space);
alloc.construct(&elem[sz], val); //add val at the end
++sz;
}
template<typename T, typename A> void vector<T, A>::resize(int newsize, T val)
{
reserve(newsize);
for (int i = sz; i < newsize; ++i)
alloc.construct(&elem[i], val); //construct
for (int i = newsize; i < sz; ++i)
alloc.destroy(&elem[i]); //destroy
sz = newsize;
}
template<typename T, typename A> std::ostream& operator<<(std::ostream& os, const vector<T, A>& obj) //requires Element<T> && Allocator<A>
{
for (const auto& x : obj)
os << x << ' ';
os << '\n';
return os;
}
template<typename T, typename A> std::istream& operator>>(std::istream& is, vector<T, A>& obj)
{
std::string line;
std::getline(is, line);
if (is.bad() || is.fail())
return is;
std::istringstream istr{ line };
vector<T, A> tmp;
while (true) {
T tmp_in = T();
istr >> tmp_in;
if (istr.fail()) {
istr.clear();
std::string invalid;
istr >> invalid;
continue;
}
tmp.push_back(tmp_in);
if (istr.eof())break;
}
for (const auto& x : tmp)
obj.push_back(x);
return is; //its sends me to xutility in this step
}
}
int main()
{
//vec::vector <int> test; //input "1 2 3 4 5" works fine with cin >>test
vec::vector <std::string> test; //input "this is a test" breaks into xutility
while (true) {
std::cin >> test; //breaks into xutility
std::cout << test << '\n';
}
}
现在出现以下问题。如果向量是向量,我可以读取向量值。因此添加1 2 3 4 5是没有问题的。 矢量工作正常。 如果我将容器类型更改为vector并通过cin&gt;&gt;读入“hello this is a test”测试;我在xutility.h中得到了一个小问题:
// MEMBER FUNCTIONS FOR _Container_base12
inline void _Container_base12::_Orphan_all() _NOEXCEPT
{ // orphan all iterators
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myproxy != 0) //It points on this line
{ // proxy allocated, drain it
_Lockit _Lock(_LOCK_DEBUG);
for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter;
*_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter)
(*_Pnext)->_Myproxy = 0;
_Myproxy->_Myfirstiter = 0;
}
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
}
Visual Studio 2017抛出: 抛出异常:读取访问冲突。这是0xC83FB858。
如何调用此标头以及它的含义是什么? 我真的不知道最新情况。
我用std :: vector替换了自定义向量,然后它也可以工作。
编辑:我稍微最小化了代码并为向量添加了命名空间。仍然是同样的行为:
vec::vector<int> test;
std::cin >> test; //Ok: Example input 1 2 3 4 5
vec::vector<std::string> test;
std::cin >> test; //Mem access violation in xutility: Example input "this is a test"