内存覆盖在我自己的 Vector 类中

Memory overwrite in my own Vector class

本文关键字:Vector 类中 自己的 我自己 覆盖 内存      更新时间:2023-10-16


对于我的算法课程项目,我们不能使用像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的好用

隐式定义的operator=做错了事。 您可以在构造函数中使用它。

因此,遵循 0/3/5 的规则:实现复制/移动构造器/赋值和析构函数,因为这是一种拥有内存管理类型。 (非资源管理类型应遵循规则 0;可复制资源管理类型应遵循规则 5。

见三法则。 实现所有析构函数/复制构造函数/移动构造函数/复制分配/移动分配,或者都不实现。

重新分配时不要按字节复制数据。 std::move从源到目标的T

在复制构造/分配中,您需要复制源T s,而不是基础字节。