vector模拟实现

目录

vector相关接口实现

使用memcpy拷贝问题

迭代器失效

引起失效的操作

指定位置元素的删除操作

​编辑引起底层空间改变的操作


vector相关接口实现

template
class vector
{
public:
	typedef T* iterator;
	typedef const T* const_iterator;
public:
	vector()
		:_start(nullptr)
		,_finish(nullptr)
		,_end_of_storage(nullptr)
	{}
	~vector()
	{
		delete[] _start;
		_start = _finish = _end_of_storage = nullptr;
	}
	iterator begin()
	{
		return _start;
	}

	iterator end()
	{
		return _finish;
	}

	const_iterator begin() const
	{
		return _start;
	}

	const_iterator end() const
	{
		return _finish;
	}
	size_t capacity()const
	{
		return _end_of_storage - _start;
	}
	const T& operator[](size_t pos) const
	{
		assert(pos < size());

		return _start[pos];
	}

	T& operator[](size_t pos)
	{
		assert(pos < size());

		return _start[pos];
	}
	size_t size() const
	{
		return _finish - _start;
	}
	void reserve(size_t n)
	{
		if (n > capacity())
		{
			size_t sz = size();
			T* tmp = new T[n];
			if (_start)
			{
				//memcpy(tmp, _start, sizeof(T) * sz);
                for (size_t i = 0; i < sz; i++)
				{
					tmp[i] = _start[i];
				}
				delete[] _start;
			}
			_start = tmp;
			_finish = _start + sz;
			_end_of_storage = _start + n;
		}
	}
	void push_back(const T& x)
	{
		assert(pos < size());
		insert(_finish, x);
	}
	void pop_back()
	{
		assert(_finish - _start > 0);
		--_finish;
	}
	void insert(iterator pos, const T& x)
	{
		assert(pos >= _start);
		assert(pos <= _finish);
		if (_finish == _end_of_storage)
		{
			//这里pos的位置也要记得改变,否者pos可能会出现问题。
			int len = pos - _start;
			reserve(capacity() = 0 ? 4 : capacity() * 2);
			pos = _len + _start;
		}
		iterator end = _finish + 1;
		while (end >= pos)
		{
			*(end) = *(end - 1);
			end--;
		}
		*end = x;
		_finish++;
	}
	iterator erase(iterator pos)
	{
		assert(pos >= _start);
		assert(pos <= _finish);
		iterator end = pos;
		whlie(end < _finish)
		{
			*(end) = *(end + 1);
			end++;
		}
		_finish--;
	}
private:
	iterator _start;
	iterator _finish;
	iterator _end_of_storage;
};

vector模拟实现_第1张图片  

vector模拟实现_第2张图片

使用memcpy拷贝问题

假设模拟实现的vector中的reserve接口中,使用memcpy进行的拷贝,以下代码会发生什么问题?

int main()
{
    vector v;
    v.push_back("1111");
    v.push_back("2222");
    v.push_back("3333");
    return 0;
}

问题分析:

  • 1. memcpy是内存的二进制格式拷贝,将一段内存空间中内容原封不动的拷贝到另外一段内存空间中
  • 2. 如果拷贝的是自定义类型的元素,memcpy既高效又不会出错,但如果拷贝的是自定义类型元素,并且自定义类型元素中涉及到资源管理时,就会出错,因为memcpy的拷贝实际是浅拷贝。

vector模拟实现_第3张图片vector模拟实现_第4张图片 vector模拟实现_第5张图片

vector模拟实现_第6张图片结论:如果对象中涉及到资源管理时,千万不能使用memcpy进行对象之间的拷贝,因为memcpy是浅拷贝,否则可能会引起内存泄漏甚至程序崩溃。

迭代器失效

迭代器失效实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间
迭代器失效有两种情况

  • 意义改变
  • 崩溃出现野指针

引起失效的操作

指定位置元素的删除操作

void test_vector4()
{
	vector v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	//1 2 3 4 5
	vector::iterator pos = find(v.begin(), v.end(), 3);
	if (pos != v.end())
	{
		v.insert(pos, 30);
	}
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	//1 2 30 3 4 5
	//删掉3
	v.erase(pos); //迭代器失效 
	//迭代器失效情况:1、pos的意义改变 2、可能会崩溃出现野指针
	//这里是意义改变
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	//1 2 30 4 5
}

vector模拟实现_第7张图片

vector模拟实现_第8张图片引起底层空间改变的操作

例如:resize,reserve,insert,assign,push_back等

void test_vector5()
{
	vector v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);
	//要求删除vector中所有偶数
	vector::iterator it = v.begin();
	while (it != v.end())
	{
		if (*it % 2 == 0) 
		{//erase(it)以后it失效,不能++
			it = v.erase(it);//erase返回删除位置it的下一个位置
		}
		else
			it++;
	}
}

你可能感兴趣的:(C++,javascript,前端,开发语言)