【问题标题】:Trying to create resize function in a vector class尝试在矢量类中创建调整大小函数
【发布时间】:2014-10-17 22:20:19
【问题描述】:

我正在制作一个复制功能here,得到了很多很好的答案,现在转向调整大小功能。我正在处理的 Vec 类如下所示:

template <class T> class Vec {

public:
//TYPEDEFS
typedef T* iterator;
typedef const T* const_iterator;
typedef unsigned int size_type;

//CONSTRUCTOS, ASSIGNMENT OPERATOR, & DESTRUCTOR
Vec() {this->create(); }
Vec(size_type n, const T& t = T()) { this->create(n, t); }
Vec(const Vec& v) { copy(v); }
Vec& operator=(const Vec& v);
~Vec() { delete [] m_data; }

//MEMBER FUNCTIONS AND OTHER OPERATORS
T& operator[] (size_type i) { return m_data[i]; }
const T& operator[] (size_type i) const { return m_data[i]; }
void push_back (const T& t);
void swap(Vec<T>& left, Vec<T>& right);
iterator erase(iterator p);
void resize(size_type n, const T& fill_in_value = T());
void clear() { delete [] m_data; create(); }
bool empty() const { return m_size == 0; }
size_type size() const { return m_size; }

//ITERATOR OPERATIONS
iterator begin() { return m_data; }
const_iterator begin() const { return m_data; }
iterator end() { return m_data + m_size; }
const_iterator end() const { return m_data + m_size; }

private:
//PRIVATE MEMBER FUNCTIONS
void create();
void create(size_type n, const T& val);
void copy(const Vec<T>& v);

//REPRESENTATION
T *m_data;      //point to first location inthe allocated array
size_type m_size;   //number of elements stored in the vector
size_type m_alloc;  //number of array locations allocated, m_size <= m_alloc
};

//create an empty vector (null pointers everywhere)
template <class T> void Vec<T>::create() {
m_data = NULL;
m_size = m_alloc = 0;   //no memory allocated yet
}

//create a vector with size n, each location having the given value
template <class T> void Vec<T>::create(size_type n, const T& val) {
m_data = new T[n];
m_size = m_alloc = n;
for (T* p = m_data; p != m_data + m_size; ++p)
    *p = val;
}   

//assign one vector to another, avoiding duplicate copying
template <class T> Vec<T>& Vec<T>::operator=(const Vec<T>& v) {
Vec<T> temp = v;
swap(*this, temp);
return *this;
}

//swap one vector with another
template <class T> void Vec<T>::swap(Vec<T>& left, Vec<T>& right) {
std::swap(left.m_size, right.m_size);
std::swap(left.m_alloc, right.m_alloc);
std::swap(left.m_data, right.m_data);
}

这是调整大小函数目前的样子:

template <class T> void Vec<T>::resize(size_type n, const T& fill_in_value) {
if (n<=m_size) {     //if resize is smaller than original size, just resize
    m_size = n;
}

else {               //if resize is bigger, assign more space at the end and fill with a value
    size_type temp = m_size;
    m_size = n;
    //for (T* p = m_data; p != m_data + temp; ++p) {
    //  std::cout << p << std::endl;
    //}
    //std::cout << std::endl;

    for (T* p = &m_data[0] + temp; p != m_data + m_size; ++p) {
    //  std::cout << p << std::endl;
        *p = fill_in_value;
    }       
}   

}

当我在程序中使用它时,我遇到了分段错误。我猜有问题:

*p = fill_in_value

所以我打印出 p 的值,它似乎为我输入的任何内容提供了适当数量的空格(8 位用于双精度等),所以从向量的开头开始就有确切的空格数调整大小,它们都有正确的位数。这里有什么我不明白的地方?

编辑:如果我改变它:

        m_size = m_alloc = n;

这是否意味着我正在为其余数据分配新内存?或者我应该创建一个具有新大小的临时向量并用它替换现有向量?我真的不明白如何纠正我没有真正调整大小而只是访问越界的问题。到目前为止,我理解它的方式是更改大小,在最后向内存地址添加内容,但将指向第一个值的指针保持不变(向量的名称)。这不起作用,所以我想知道我的概念误解是什么。

EDIT2:我已根据此处的答案对代码进行了更正,并且可以正常工作:

template <class T> void Vec<T>::resize(size_type n, const T& fill_in_value) {
if (n<=m_size) {
    m_size = m_alloc = n;
}

else {
    T* new_data = new T[n];
    for (size_type i = 0; i < m_size; i++) {
        new_data[i] = m_data[i];
    }
    for (size_type i = m_size; i < n; i++) {
        new_data[i] = fill_in_value;
    }
    delete m_data;
    m_data = new_data;
    m_size = m_alloc = n;               
}           


}

【问题讨论】:

  • 仅供参考,您应该使用placement-new 和raw-memory-storage 来处理这些事情
  • 您实际上并没有“调整”保存数据的数组的大小。您只是在越界访问它。
  • 你在哪里为其他元素分配了空间?

标签: c++ vector dynamic-allocation


【解决方案1】:

您实际上并没有为新元素分配空间。当新尺寸大于当前尺寸时,您应该分配新的存储空间并将现有元素复制到那里。

T* new_data = new T[n];
for ( size_type i = 0; i < m_size; ++i )
{
    new_data[i] = m_data[i];
}
for ( size_type i = m_size; i < n; ++i )
{
    new_data[i] = fill_in_value;
}
delete m_data;
m_data = new_data;
m_size = n;

【讨论】:

  • 谢谢,这行得通。 new_data 最终会在某处被删除吗?
  • 好吧,new_data 变成了你的 m_data,最终在你的析构函数中被删除 ~Vec()
猜你喜欢
  • 1970-01-01
  • 2014-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 2021-10-01
相关资源
最近更新 更多