malloc vs new¶
Why is this crashing at malloc?
template <typename T>
void vector<T>::push_back(T x) {
if (m_size + 1 > m_capacity) {
m_capacity = m_capacity << 1;
T* items = (T*)malloc(m_capacity * sizeof(T));
if (!items) {
std::cout << "\e[31mERROR:\e[0m could not allocate memory!\n";
exit(1);
}
print("Allocated memory of %zu bytes!\n", m_capacity);
memcpy(items, m_items, m_size);
delete[] m_items;
m_items = items;
}
m_items[m_size++] = x;
}
The problem is with this line:
Issues:¶
-
Incorrect memcpy size:
-
memcpy expects the size in bytes, but m_size is likely the number of elements, not the number of bytes.
-
β Correct version:
-
malloc with new[]/delete[] mismatch:
-
You are using malloc() for allocation but delete[] for deallocation, which is incorrect in C++. malloc() should be paired with free() and new[] should be paired with delete[].
-
β You should either:
- Replace malloc with new:
- OR replace delete[] with free() (less ideal for C++):
-
Missing copy constructor call:
-
memcpy is not suitable for objects with non-trivial copy constructors, destructors, or assignment operators. For C++ objects, std::copy() or std::move() should be used instead:
- β Use std::copy:
-
Fixed Code:¶
template <typename T>
void vector<T>::push_back(T x) {
if (m_size + 1 > m_capacity) {
m_capacity = m_capacity << 1;
T\* items = new T[m_capacity];
if (!items) {
std::cout << "\e[31mERROR:\e[0m could not allocate memory!\n";
exit(1);
}
std::copy(m_items, m_items + m_size, items);
delete[] m_items;
m_items = items;
}
m_items[m_size++] = x;
}
Fixes Summary:¶
βοΈ Use new[] instead of malloc()
βοΈ Use std::copy() instead of memcpy() for object copying
βοΈ Ensure correct size is passed to memcpy (if using it for POD types)
βοΈ Pair new[] with delete[] (or malloc with free)
Ah, got it! The reason lies in how memory allocation works in C++ versus C.
π C++ vs C Memory Allocation¶
malloc()¶
- malloc() comes from C and allocates raw, uninitialized memory.
- It does not call constructors for objects of class types.
- Deallocation is done using free().
new[]¶
- new[] comes from C++ and allocates memory while also calling constructors for objects of class types.
- It sets up the memory properly for C++ objects (including setting up virtual tables, etc.).
- Deallocation is done using delete[].
π¨ Why It Crashes¶
- You allocate memory using malloc() β constructor is NOT called.
- You deallocate using delete[] β delete[] expects that the constructor was called to properly initialize the object.
- Since the constructor wasnβt called, delete[] tries to clean up something that was never initialized β undefined behavior β crash.
β Solution¶
- If you use malloc(), pair it with free() β but that means you canβt use class types properly (because constructors wonβt be called).
- If youβre working with C++ objects, you should use new[] because it will ensure the constructor is called and the object lifecycle is managed correctly.
- This is why switching to new[] (and delete[]) is the right fix in C++.