I was making a copy function here, got a lot of good answers, now moving on to a resize function. The Vec class I'm working on looks like this:
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);
}
This is what the resize function looks like so far:
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;
}
}
}
When I use this in a program, I get a segmentation fault. I'm guessing there is something wrong with:
*p = fill_in_value
So I print out the values of p and it seems to give the appropriate number of spaces for whatever I put in (8 bits for a double, etc), so from the beginning of the vector there are exactly the number of spaces to resize and they all have the right number of bits. What is it that I am not understanding here?
EDIT: If I change it so that:
m_size = m_alloc = n;
does that mean that I am allocating new memory for the rest of the data? Or should I create a temporary vector with the new size and replace the existing vector with that? I don't really understand how to correct the issue that I am not truly resizing, but just accessing out of bounds. The way I am understanding it so far is that I change the size, add stuff to the memory addresses at the end, but leave the pointer to the first value the same (the name of the vector). This is not working, so I'm wondering what my conceptual misunderstanding is.
EDIT2: I've made this correction to the code based on the answers here and it works:
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;
}
}