CS 112
Introduction to Data Structures
Week 04
Vectors: Dynamic Arrays
Eric Araújo
Calvin University · Fall 2026
new and deletelist grows on demand. This week we build that, and find out what it costs.
int *arr = new int[capacity]; // ask the OS for space
arr[0] = 42; // use it like an array
delete [] arr; // give it back
arr = nullptr; // don't keep the address
new returns the address of the blockdelete [] for arrays, plain delete for single objectsnew needs exactly one matching delete. Forget it and you leak; do it twice and you corrupt the heap.new hands you
class Vec {
public:
Vec();
Vec(const Vec &original); // copy constructor
~Vec(); // destructor
unsigned getSize() const;
void append(const Item &it);
Item& operator[](unsigned i);
private:
Item *myArray; // heap block
unsigned mySize; // slots in use
unsigned myCapacity; // slots available
};
void Vec::append(const Item &it) {
myArray[mySize] = it;
++mySize;
}
void Vec::append(const Item &it) {
if (mySize == myCapacity) {
unsigned cap = (myCapacity == 0) ? 1 : myCapacity*2;
Item *bigger = new Item[cap];
for (unsigned i = 0; i < mySize; ++i) {
bigger[i] = myArray[i]; // copy everything
}
delete [] myArray; // release the old
myArray = bigger;
myCapacity = cap;
}
myArray[mySize] = it;
++mySize;
}
Vec::~Vec() {
delete [] myArray;
myArray = nullptr;
}
C++ writes a destructor for you, but it only destroys the members. It destroys the pointer, not what the pointer points at.
new, your class must define a destructor.
Otherwise every Vec that dies leaves its heap block behind.
deletemain(), for every objectdelete them; members when their owner dies. There is no garbage collector: the rules are exact and predictable.
Vec a;
a.append(3);
a.append(7);
Vec b = a; // what exactly got copied?
b[0] also changes a[0]
Vec::Vec(const Vec &orig) {
mySize = orig.mySize;
myCapacity = orig.myCapacity;
myArray = new Item[myCapacity]; // our OWN block
for (unsigned i = 0; i < mySize; ++i) {
myArray[i] = orig.myArray[i]; // copy the values
}
}
a and b are independent, and each destructor frees its own block.
Vec b = a; // 1. explicit copy
void show(Vec v); // 2. pass-by-value
show(a);
Vec makeVec() { // 3. return by value
Vec local;
return local;
}
show() copies the whole heap block.Watching a shallow copy destroy itself.
(two objects, one array, zero survivors)
operator[]
Item& Vec::operator[](unsigned i) {
return myArray[i]; // a reference, not a copy
}
v[2] = 99; // works because v[2] IS the slot
Item and you get a copy, assigning to it would change a temporary and vanish. Returning Item& makes the call an alias for the element.this Pointer
def set_first(self, v):
self.my_first = v
void setFirst(Item v) {
this->myFirst = v;
}
this: a pointer to the object the method was called on. You rarely write it, but it's there, and this->x is just (*this).x.new gets heap memory at runtime; every new needs one deletenew, it needs a destructor
This deck stands on earlier CS112 materials by
Joel Adams and Victor Norman · adapted and extended by Eric Araújo