【发布时间】:2017-05-11 19:20:44
【问题描述】:
对于我的算法课程项目,我们不能使用像 std::vector 这样的 STL 东西,所以我正在尝试实现我自己的版本(使用模板)。
它似乎有效,但是当我声明 Vector< Vector< int > >
时,.push() 方法开始覆盖内存。
更具体地说,使用以下代码:
Vector<Vector<int>> v(3);
cout << v[0].push(0) << "\n";
cout << v[0].push(55) << "\n";
cout << v[0].push(4) << "\n";
cout << v[1].push(12) << "\n";
cout << v[1].push(3) << "\n";
cout << v[2].push(1) << "\n";
输出是这样的(.push()返回插入元素的地址):
0x561328b0bc20
0x561328b0bc24
0x561328b0bc28
0x561328b0bc20
0x561328b0bc24
0x561328b0bc20
关于为什么会发生这种情况的任何建议?
这是我的Vector 课程的代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
template<class T>
class Vector {
private:
size_t _size;
size_t _capacity;
char* _buffer; //char* for performance
void _realloc(size_t);
public:
Vector(size_t s=0, T def=T());
T* push(T);
T& operator[](int);
size_t size() { return _size; }
};
template<class T>
void Vector<T>:: _realloc(size_t ncap)
{
_capacity = ncap;
char* nbuf = _buffer;
_buffer = new char[_capacity];
for(size_t i=0; i<_size * sizeof(T); ++i)
_buffer[i] = nbuf[i];
delete[] nbuf;
}
/*
* s -> size
* def -> default value
*/
template<class T>
Vector<T>:: Vector(size_t s, T def) : _size(s)
{
_capacity = 32;
while(_capacity < _size)
_capacity *= 2;
_buffer = new char[_capacity * sizeof(T)];
for(size_t i=0; i<_size; ++i)
((T*)_buffer)[i] = def;
}
/*
* check capacity, reallocs if necessary and push the element
* then return the addres (used only for debug)
*/
template<class T>
T* Vector<T>:: push(T ele)
{
if(_capacity == _size)
_realloc(2 * _capacity);
((T*)_buffer)[_size++] = ele;
return &((T*)_buffer)[_size-1];
}
template<class T>
T& Vector<T>:: operator[](int i)
{
if(i<0 or i>=(int)_size) {
cerr << "Out of bounds!\n";
abort();
}else
return ((T*)_buffer)[i];
}
template<class T>
ostream& operator<<(ostream& out, Vector<T>& v)
{
out << "{";
if(v.size() > 0) {
out << v[0];
for(size_t i=1; i<v.size(); ++i)
out << ", " << v[i];
}
out << "}";
return out;
}
谢谢!
PS:我知道 C++ 不好用:P
【问题讨论】:
-
请发送minimal reproducible example。如果问题在此过程中没有自行解决,我们将能够为您提供帮助
-
如果您想知道,是的,我在阅读您的问题时不小心跳过了链接。对此感到抱歉。不过,请注意在您的问题中填写所有相关信息。
-
好吧,@Quentin 在我投票结束后大约 5 秒解决了我的问题。投票重新开放。题外话:
#include <bits/stdc++.h>结合using namespace std;是一个偷偷摸摸的错误工厂。不要使用#include(many reasons) 并阅读Why is “using namespace std” considered bad practice?。 -
还要小心使用下划线前缀的位置和方式。 They often have special meaning in C++
标签: c++ c++11 memory-management