Practice Questions — Dynamic Memory Allocation (new, delete)
← Back to NotesTopic-Specific Questions
Question 1
Easy
What is the output of the following code?
int* p = new int(42);
cout << *p;
delete p;new int(42) allocates an int on the heap and initializes it to 42.
42Question 2
Easy
What is the output?
int* arr = new int[3]();
cout << arr[0] << " " << arr[1] << " " << arr[2];
delete[] arr;The parentheses () after new int[3] value-initialize all elements.
0 0 0Question 3
Easy
What is the output?
int* p = new int(10);
*p += 5;
cout << *p;
delete p;*p += 5 adds 5 to the value stored at the heap location.
15Question 4
Easy
What is the output?
int x = 100;
int* p = &x;
int* q = new int(200);
cout << *p << " " << *q;
delete q;p points to a stack variable; q points to a heap variable.
100 200Question 5
Medium
What is the output?
int* arr = new int[5]{10, 20, 30, 40, 50};
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += arr[i];
}
cout << sum;
delete[] arr;Sum all five elements.
150Question 6
Medium
What is the output?
class Box {
public:
int value;
Box(int v) : value(v) {
cout << "Box(" << v << ") ";
}
~Box() {
cout << "~Box(" << value << ") ";
}
};
Box* b = new Box(42);
cout << b->value << " ";
delete b;new calls the constructor, delete calls the destructor.
Box(42) 42 ~Box(42) Question 7
Medium
What is the output?
int** matrix = new int*[2];
matrix[0] = new int[2]{1, 2};
matrix[1] = new int[2]{3, 4};
cout << matrix[0][0] + matrix[1][1];
delete[] matrix[0];
delete[] matrix[1];
delete[] matrix;matrix[0][0] is the top-left, matrix[1][1] is the bottom-right.
5Question 8
Medium
What is the output?
int* p = new int(10);
int* q = p; // q points to same memory
*q = 20;
cout << *p << endl;
delete p;
// delete q; // Would this be correct?Both p and q point to the same heap memory. Only one delete is needed.
20(Deleting q would be a double-free error since p already freed the memory)
Question 9
Hard
What is the output?
class Counter {
static int count;
public:
Counter() { count++; cout << "+" << count << " "; }
~Counter() { cout << "-" << count << " "; count--; }
};
int Counter::count = 0;
Counter* arr = new Counter[3];
cout << "| ";
delete[] arr;new[] calls the constructor for each element. delete[] calls the destructor for each element in reverse order.
+1 +2 +3 | -3 -2 -1 Question 10
Hard
What is the output?
#include
using namespace std;
auto p1 = make_shared(10);
cout << "count: " << p1.use_count() << endl;
{
auto p2 = p1;
*p2 += 5;
cout << "count: " << p1.use_count() << endl;
cout << "value: " << *p1 << endl;
}
cout << "count: " << p1.use_count() << endl;
cout << "value: " << *p1 << endl; shared_ptr uses reference counting. Copying increments the count; destruction decrements it.
count: 1count: 2value: 15count: 1value: 15Mixed & Application Questions
Question 1
Easy
What is the difference between stack memory and heap memory?
Think about lifetime, speed, size, and who manages the memory.
Stack: Automatic allocation/deallocation, very fast, limited size (1-8 MB), variables destroyed at scope end. Heap: Manual allocation (new) and deallocation (delete), slower, much larger (limited by system RAM), variables persist until explicitly freed.
Question 2
Easy
What is a memory leak? How does it happen?
Think about what happens when you lose the pointer to heap memory.
A memory leak occurs when dynamically allocated memory (via
new) is never freed (via delete). It happens when: (1) a pointer to heap memory goes out of scope without delete, (2) a pointer is reassigned without freeing the old memory, (3) an exception is thrown before delete is reached.Question 3
Easy
What is the output?
int* p = new int;
*p = 7;
int* q = new int;
*q = 3;
cout << *p + *q;
delete p;
delete q;Each new allocates a separate int. Add the dereferenced values.
10Question 4
Medium
What is the output?
int* createArray(int size) {
int* arr = new int[size];
for (int i = 0; i < size; i++)
arr[i] = i * 2;
return arr;
}
int* data = createArray(4);
for (int i = 0; i < 4; i++)
cout << data[i] << " ";
delete[] data;The function allocates on the heap and returns the pointer. The caller frees it.
0 2 4 6 Question 5
Medium
What is RAII and why is it important in C++?
Think about tying resource lifetime to object lifetime.
RAII (Resource Acquisition Is Initialization) means acquiring resources in the constructor and releasing them in the destructor. When the object goes out of scope, the destructor runs automatically, ensuring cleanup even if an exception is thrown. This eliminates memory leaks, file handle leaks, and lock leaks.
Question 6
Medium
What is the output?
class Tracker {
public:
string name;
Tracker(string n) : name(n) { cout << "C:" << name << " "; }
~Tracker() { cout << "D:" << name << " "; }
};
Tracker t1("stack");
cout << "| ";
Tracker* t2 = new Tracker("heap");
cout << "| ";
delete t2;
cout << "| ";(Assume this is inside main, and t1 is a local variable)
Stack objects are destroyed at scope end; heap objects are destroyed at delete.
C:stack | C:heap | D:heap | (D:stack would print after main returns)
Question 7
Hard
What is the output?
#include
using namespace std;
auto p1 = make_unique(100);
cout << *p1 << endl;
auto p2 = move(p1); // transfer ownership
cout << *p2 << endl;
if (p1 == nullptr)
cout << "p1 is null" << endl; unique_ptr cannot be copied but can be moved. After move, the source becomes nullptr.
100100p1 is nullQuestion 8
Hard
What is the output?
int** arr = new int*[3];
for (int i = 0; i < 3; i++) {
arr[i] = new int(i * 10);
}
for (int i = 0; i < 3; i++) {
cout << *arr[i] << " ";
}
for (int i = 0; i < 3; i++) {
delete arr[i];
}
delete[] arr;arr is an array of pointers, each pointing to a single int on the heap.
0 10 20 Question 9
Hard
What is the difference between unique_ptr, shared_ptr, and weak_ptr?
Think about ownership semantics.
unique_ptr: Sole ownership. Cannot be copied, only moved. Memory freed when it goes out of scope. Use for exclusive ownership. shared_ptr: Shared ownership via reference counting. Memory freed when the last shared_ptr is destroyed. Use when multiple parts of code need the same resource. weak_ptr: Non-owning observer of a shared_ptr. Does not affect the reference count. Used to break circular references.
Multiple Choice Questions
MCQ 1
Which operator is used to allocate memory on the heap in C++?
Answer: C
C is correct. The
C is correct. The
new operator allocates memory on the heap in C++. malloc (A) is a C function that also works in C++ but does not call constructors. alloc (B) and create (D) are not C++ operators.MCQ 2
What must you use to free memory allocated with new int[10]?
Answer: B
B is correct.
B is correct.
new[] must be paired with delete[]. Plain delete (A) is for single allocations. free (C) is for C's malloc. remove (D) is not a memory management operator.MCQ 3
Where is dynamically allocated memory stored?
Answer: B
B is correct. Memory allocated with
B is correct. Memory allocated with
new resides on the heap. Local variables go on the stack (A). The code segment (C) stores compiled instructions. Registers (D) are CPU storage, not programmer-accessible.MCQ 4
What is a memory leak?
Answer: B
B is correct. A memory leak is dynamically allocated memory that the program never frees. Accessing freed memory (A) is a dangling pointer issue. Null pointer dereference (C) is a different bug. Using stack for large data (D) risks stack overflow, not a leak.
B is correct. A memory leak is dynamically allocated memory that the program never frees. Accessing freed memory (A) is a dangling pointer issue. Null pointer dereference (C) is a different bug. Using stack for large data (D) risks stack overflow, not a leak.
MCQ 5
What does new int[5]() do?
Answer: B
B is correct. The parentheses
B is correct. The parentheses
() after the array size perform value-initialization, which initializes all elements to 0 for primitive types. Without the parentheses, elements would be uninitialized (A).MCQ 6
What happens if you call delete on a stack variable?
Answer: C
C is correct. Calling
C is correct. Calling
delete on memory not allocated with new is undefined behavior. It can corrupt the heap allocator and crash the program. The compiler does not catch this error (D is false).MCQ 7
What is the typical size of the stack in a C++ program?
Answer: B
B is correct. The default stack size is typically 1-8 MB depending on the operating system and compiler. Exceeding this limit causes a stack overflow. The heap (not the stack) can grow to use most available system memory.
B is correct. The default stack size is typically 1-8 MB depending on the operating system and compiler. Exceeding this limit causes a stack overflow. The heap (not the stack) can grow to use most available system memory.
MCQ 8
What does RAII stand for?
Answer: C
C is correct. RAII (Resource Acquisition Is Initialization) ties resource lifetime to object lifetime. Resources are acquired in the constructor and released in the destructor, ensuring automatic cleanup.
C is correct. RAII (Resource Acquisition Is Initialization) ties resource lifetime to object lifetime. Resources are acquired in the constructor and released in the destructor, ensuring automatic cleanup.
MCQ 9
What happens if new fails to allocate memory?
Answer: C
C is correct. By default,
C is correct. By default,
new throws std::bad_alloc if allocation fails. If you want nullptr instead, use the nothrow version: int* p = new(nothrow) int;.MCQ 10
Which smart pointer allows shared ownership of a resource?
Answer: B
B is correct.
B is correct.
shared_ptr uses reference counting to allow multiple pointers to share ownership. unique_ptr (A) is exclusive ownership. weak_ptr (C) is a non-owning observer. auto_ptr (D) is deprecated since C++11.MCQ 11
What is wrong with this code?
unique_ptr p1 = make_unique(10);
unique_ptr p2 = p1; Answer: B
B is correct.
B is correct.
unique_ptr has exclusive ownership and its copy constructor is deleted. You must use move: unique_ptr p2 = move(p1); . After the move, p1 becomes nullptr.MCQ 12
In what order should a dynamic 2D array (int**) be deallocated?
Answer: B
B is correct. Each row must be freed first (
B is correct. Each row must be freed first (
delete[] matrix[i]), then the outer array (delete[] matrix). If you free the outer array first (A), you lose the pointers to the rows and cannot free them.MCQ 13
What is double-free?
Answer: B
B is correct. Double-free is calling
B is correct. Double-free is calling
delete on the same pointer twice. It is undefined behavior that can corrupt the heap allocator. Deleting a null pointer (A) is safe and does nothing.Coding Challenges
Challenge 1: Dynamic Array with User Input
EasyWrite a program that reads n from the user, dynamically allocates an array of n integers, reads n values from the user, prints them in reverse order, and properly frees the memory.
Sample Input
4
10 20 30 40
Sample Output
Reverse: 40 30 20 10
Use new[] to allocate and delete[] to free. Do not use vector.
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int* arr = new int[n];
for (int i = 0; i < n; i++) cin >> arr[i];
cout << "Reverse: ";
for (int i = n - 1; i >= 0; i--) cout << arr[i] << " ";
cout << endl;
delete[] arr;
return 0;
}Challenge 2: Dynamic String Array
EasyDynamically allocate an array of n strings, read names from the user, and print them with their index. Free the memory properly.
Sample Input
3
Arjun Priya Kavitha
Sample Output
0: Arjun
1: Priya
2: Kavitha
Use new string[n] and delete[]. Use getline or cin for input.
#include <iostream>
#include <string>
using namespace std;
int main() {
int n;
cin >> n;
string* names = new string[n];
for (int i = 0; i < n; i++) cin >> names[i];
for (int i = 0; i < n; i++) cout << i << ": " << names[i] << endl;
delete[] names;
return 0;
}Challenge 3: Resizable Array (Manual)
MediumWrite a class ResizableArray that starts with capacity 4. It has push(int val) which adds an element, doubling capacity if full. It has print() which prints all elements. Use new/delete internally.
Sample Input
(Push 1, 2, 3, 4, 5, 6)
Sample Output
Elements: 1 2 3 4 5 6
Capacity: 8
Implement manual resizing using new/delete. Double the capacity when full.
#include <iostream>
using namespace std;
class ResizableArray {
int* data;
int size;
int capacity;
void resize() {
capacity *= 2;
int* newData = new int[capacity];
for (int i = 0; i < size; i++) newData[i] = data[i];
delete[] data;
data = newData;
}
public:
ResizableArray() : size(0), capacity(4) {
data = new int[capacity];
}
~ResizableArray() { delete[] data; }
void push(int val) {
if (size == capacity) resize();
data[size++] = val;
}
void print() {
cout << "Elements: ";
for (int i = 0; i < size; i++) cout << data[i] << " ";
cout << endl;
cout << "Capacity: " << capacity << endl;
}
};
int main() {
ResizableArray arr;
for (int i = 1; i <= 6; i++) arr.push(i);
arr.print();
return 0;
}Challenge 4: Dynamic Matrix Addition
MediumWrite a program that dynamically allocates two m x n matrices, fills them with user input, computes their sum in a third dynamic matrix, prints the result, and frees all memory.
Sample Input
2 2
1 2
3 4
5 6
7 8
Sample Output
Sum:
6 8
10 12
Use int** for all matrices. Free all memory in reverse order.
#include <iostream>
using namespace std;
int** allocMatrix(int r, int c) {
int** m = new int*[r];
for (int i = 0; i < r; i++) m[i] = new int[c];
return m;
}
void freeMatrix(int** m, int r) {
for (int i = 0; i < r; i++) delete[] m[i];
delete[] m;
}
int main() {
int r, c;
cin >> r >> c;
int** a = allocMatrix(r, c);
int** b = allocMatrix(r, c);
int** sum = allocMatrix(r, c);
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++) cin >> a[i][j];
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++) cin >> b[i][j];
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++) sum[i][j] = a[i][j] + b[i][j];
cout << "Sum:" << endl;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) cout << sum[i][j] << " ";
cout << endl;
}
freeMatrix(a, r);
freeMatrix(b, r);
freeMatrix(sum, r);
return 0;
}Challenge 5: Student Database with Dynamic Objects
HardCreate a Student class with name and marks. Dynamically allocate an array of n Student objects on the heap, fill with user data, find the topper, and print all students. Free memory properly.
Sample Input
3
Rahul 85
Priya 92
Arun 78
Sample Output
All Students:
1. Rahul - 85
2. Priya - 92
3. Arun - 78
Topper: Priya (92)
Use new Student[n] and delete[]. Implement a display() method in the class.
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
string name;
int marks;
Student() : name(""), marks(0) {}
Student(string n, int m) : name(n), marks(m) {}
void display(int idx) {
cout << idx << ". " << name << " - " << marks << endl;
}
};
int main() {
int n;
cin >> n;
Student* students = new Student[n];
for (int i = 0; i < n; i++) {
string name; int marks;
cin >> name >> marks;
students[i] = Student(name, marks);
}
cout << "All Students:" << endl;
for (int i = 0; i < n; i++) students[i].display(i + 1);
int topIdx = 0;
for (int i = 1; i < n; i++)
if (students[i].marks > students[topIdx].marks) topIdx = i;
cout << "Topper: " << students[topIdx].name << " (" << students[topIdx].marks << ")" << endl;
delete[] students;
return 0;
}Challenge 6: RAII Wrapper for Dynamic Array
HardImplement a SafeArray class that wraps a dynamic int array with RAII. The class should support: constructor(int size), destructor, operator[] for access, size() method, and fill(int value). Demonstrate that memory is freed automatically without explicit delete.
Sample Input
(No input required)
Sample Output
Array created with size 5
Filled: 42 42 42 42 42
Modified: 42 42 99 42 42
Array destroyed (5 elements freed)
The destructor must free the memory. No manual delete should be needed outside the class.
#include <iostream>
using namespace std;
class SafeArray {
int* data;
int len;
public:
SafeArray(int n) : len(n), data(new int[n]()) {
cout << "Array created with size " << n << endl;
}
~SafeArray() {
delete[] data;
cout << "Array destroyed (" << len << " elements freed)" << endl;
}
int& operator[](int i) { return data[i]; }
int size() const { return len; }
void fill(int val) {
for (int i = 0; i < len; i++) data[i] = val;
}
void print() {
for (int i = 0; i < len; i++) cout << data[i] << " ";
cout << endl;
}
};
int main() {
SafeArray arr(5);
arr.fill(42);
cout << "Filled: ";
arr.print();
arr[2] = 99;
cout << "Modified: ";
arr.print();
// No delete needed! Destructor handles cleanup
return 0;
}Need to Review the Concepts?
Go back to the detailed notes for this chapter.
Read Chapter NotesWant to learn C++ with a live mentor?
Explore our C++ Masterclass