Unit 5: Dynamic Memory Management and Polymorphism - Practice Quiz

CSE202 — Object Oriented Programming 60 Questions
0 Correct 0 Wrong 60 Left
0/60

1 Which C++ operator allocates memory dynamically?

Dynamic memory allocation using new and delete operators Easy
A. delete
B. sizeof
C. new
D. typedef

2 Which statement correctly releases an integer allocated as int* p = new int;?

Dynamic memory allocation using new and delete operators Easy
A. delete[] p;
B. remove(p);
C. delete p;
D. free(p);

3 Which statement correctly releases an array allocated as int* a = new int[10];?

Dynamic memory allocation using new and delete operators Easy
A. delete[] a;
B. free[] a;
C. delete a;
D. clear[] a;

4 Why is a base-class destructor commonly declared virtual?

Virtual destructors Easy
A. To destroy derived objects correctly
B. To allocate objects dynamically
C. To overload the destructor
D. To prevent object construction

5 Which C++ feature is an example of compile-time polymorphism?

Compile-time polymorphism Easy
A. Function overloading
B. Abstract classes
C. Dynamic allocation
D. Virtual functions

6 When is compile-time polymorphism resolved?

Compile-time polymorphism Easy
A. During execution
B. During destruction
C. During allocation
D. During compilation

7 Which combination is commonly used to achieve run-time polymorphism in C++?

Run-time polymorphism Easy
A. Structures and global variables
B. Constructors and static members
C. Inheritance and virtual functions
D. Templates and overloaded functions

8 In run-time polymorphism, when is the function implementation selected?

Run-time polymorphism Easy
A. While the file saves
B. While the code preprocesses
C. While the program runs
D. While the source compiles

9 Which keyword declares a virtual function in C++?

Virtual functions Easy
A. friend
B. static
C. virtual
D. explicit

10 Where is a virtual function initially declared for use in an inheritance hierarchy?

Virtual functions Easy
A. In the main function
B. In the base class
C. In a namespace only
D. In a local block

11 What does a dynamic constructor typically do?

Dynamic constructors Easy
A. Overloads a virtual destructor
B. Deletes memory before construction
C. Converts a class into a template
D. Allocates memory during construction

12 Which operator is commonly used inside a dynamic constructor?

Dynamic constructors Easy
A. delete
B. new
C. sizeof
D. return

13 Which statement about an abstract class is correct?

Abstract classes and concrete classes Easy
A. It cannot be instantiated directly
B. It cannot contain data members
C. It cannot have constructors
D. It cannot be inherited

14 What is a concrete class?

Abstract classes and concrete classes Easy
A. A class with only static members
B. A class that can be instantiated
C. A class that cannot be inherited
D. A class with no member functions

15 What does a self-referential class contain?

Introduction to self-referential class Easy
A. An object of its own class type
B. A pointer to its own class type
C. Only a reference to a function
D. Only a pointer to an integer

16 Which syntax declares show as a pure virtual function?

Pure virtual functions Easy
A. virtual void show() = 0;
B. void virtual = show();
C. virtual void show() = 1;
D. static void show() = 0;

17 What usually happens when a class contains a pure virtual function?

Pure virtual functions Easy
A. The class becomes static
B. The class becomes a template
C. The class becomes abstract
D. The class becomes immutable

18 Which type of binding is generally associated with non-virtual function calls?

Early binding and late binding Easy
A. Deferred binding
B. Late binding
C. Dynamic binding
D. Early binding

19 Which type of binding is associated with virtual function calls through a base pointer?

Early binding and late binding Easy
A. Lexical binding
B. Late binding
C. Static binding
D. Early binding

20 Which situation causes a memory leak?

Memory leaks and allocation failures Easy
A. Allocated memory is released once
B. Allocated memory is never released
C. A pointer is initialized to nullptr
D. A local variable leaves scope

21 Which statement correctly releases the memory allocated by int* values = new int[10];?

Dynamic memory allocation using new and delete operators Medium
A. values = nullptr;
B. delete values;
C. free(values);
D. delete[] values;

22 Consider the following code:

CPP
int* p = new int(25);
int* q = p;
delete p;



What is the state of q after delete p;?

Dynamic memory allocation using new and delete operators Medium
A. It owns a new copy of 25
B. It is a dangling pointer
C. It points to an integer containing 0
D. It becomes nullptr automatically

23 What change is required to ensure that both destructors execute when a derived object is deleted through a base-class pointer?

Virtual destructors Medium
A. Make the base destructor virtual
B. Make the base constructor virtual
C. Make the derived destructor static
D. Make the derived constructor explicit

24 Given the following declarations, which operation has undefined behavior because Base does not have a virtual destructor?

CPP
class Base {
public:
    ~Base() {}
};

class Derived : public Base {
public:
    ~Derived() {}
};

Virtual destructors Medium
A. Derived* p = new Derived; delete p;
B. Base* p = new Derived; delete p;
C. delete new Base;
D. delete new Derived;

25 A class defines print(int) and print(double). When print(7) is called, how is the selected function determined?

Compile-time polymorphism Medium
A. By the argument type during compilation
B. By the object's allocated address
C. By the run-time type of the object
D. By the function definition order

26 Which C++ feature provides compile-time polymorphism without requiring inheritance?

Compile-time polymorphism Medium
A. Virtual functions
B. Function overloading
C. Dynamic casting
D. Abstract base classes

27 Suppose Derived overrides the virtual function show() inherited from Base. What does the following code call?

CPP
Base* p = new Derived;
p->show();

Run-time polymorphism Medium
A. Neither version without a cast
B. Both versions in declaration order
C. Base::show() in every case
D. Derived::show() through dynamic dispatch

28 Which combination is necessary for run-time polymorphism when calling an overridden member function?

Run-time polymorphism Medium
A. Inheritance and a virtual function
B. Friendship and a constant object
C. Templates and an overloaded operator
D. Composition and a static function

29 What is the purpose of writing override in the following declaration?

CPP
void process() override;

Virtual functions Medium
A. It verifies that a virtual function is overridden
B. It makes process() a static function
C. It prevents calls through base pointers
D. It creates an overload for every type

30 Assume Base::display() is virtual and Derived::display() overrides it. Which call explicitly bypasses virtual dispatch for an object d of type Derived?

Virtual functions Medium
A. static_cast<Base&>(d).display();
B. d.Base::display();
C. d.display();
D. (&d)->display();

31 A class constructor allocates an array using data = new int[size];. Which class member should normally release this resource?

Dynamic constructors Medium
A. The copy constructor
B. The class destructor
C. The virtual function
D. The default argument

32 A class owns a dynamically allocated array through a raw pointer. Why is the compiler-generated copy constructor usually unsuitable?

Dynamic constructors Medium
A. It prevents all object copying
B. It converts the pointer to void*
C. It allocates an oversized array
D. It performs a shallow pointer copy

33 Given class Shape { public: virtual double area() const = 0; };, which class is concrete?

Abstract classes and concrete classes Medium
A. A class that leaves area() unimplemented
B. A class that declares another pure virtual function
C. A class that inherits Shape but adds only data members
D. A class that implements double area() const override

34 Which declaration is valid when Shape is an abstract class?

Abstract classes and concrete classes Medium
A. Shape copy = Shape();
B. Shape object;
C. Shape* pointer = nullptr;
D. Shape objects[3];

35 Which member declaration correctly makes Node a self-referential class suitable for a singly linked list?

Introduction to self-referential class Medium
A. Node* next;
B. static Node next;
C. Node next;
D. virtual Node next;

36 Consider struct Node { int value; Node* next; };. What should next contain for the final node of a non-circular linked list?

Introduction to self-referential class Medium
A. A null pointer value
B. The address of the first node
C. An uninitialized pointer value
D. The address of the final node

37 Which declaration makes calculate() a pure virtual function?

Pure virtual functions Medium
A. virtual int calculate() == 0;
B. int calculate() override = 0;
C. virtual int calculate() = 0;
D. static int calculate() = 0;

38 Class B inherits from an abstract class containing two pure virtual functions. B overrides only one of them. What follows?

Pure virtual functions Medium
A. B remains an abstract class
B. B cannot define any constructors
C. B becomes a concrete class
D. B loses access to base members

39 A non-virtual member function is called through a Base* that points to a Derived object. Which class's function is selected?

Early binding and late binding Medium
A. Both functions sequentially
B. The function from Derived
C. The function selected at run time
D. The function from Base

40 Which call is resolved using late binding?

Early binding and late binding Medium
A. A static function called through a class name
B. An overloaded function called with an integer
C. A qualified base function called by name
D. A virtual function called through a base reference

41 Consider the following standard C++ code:

CPP
int* p = new int[0];
delete[] p;



Assuming the new expression completes successfully, which statement is guaranteed?

Dynamic memory allocation using new and delete operators Hard
A. delete[] p has undefined behavior because no elements were constructed.
B. p must be a null pointer because the requested array is empty.
C. p is a pointer value that may validly be passed to delete[].
D. p points to one default-initialized int used as an array sentinel.

42 What is the behavior of the following program fragment?

CPP
int* p = new int[4];
delete p;

Dynamic memory allocation using new and delete operators Hard
A. It has undefined behavior because the allocation and deallocation forms do not match.
B. It destroys only the first element and safely releases the complete allocation.
C. It is well-defined because int has a trivial destructor and no array cleanup is needed.
D. It causes a compile-time error because delete can detect every array allocation.

43 Consider:

CPP
struct Base {
    virtual void run() {}
    ~Base() {}
};

struct Derived : Base {
    int* data = new int[100];
    ~Derived() { delete[] data; }
};

Base* p = new Derived;
delete p;



Which conclusion is correct?

Virtual destructors Hard
A. The deletion has undefined behavior because Base::~Base is not virtual.
B. The compiler selects Derived::~Derived from the dynamic allocation type.
C. Both destructors run because another member function in Base is virtual.
D. Only Base::~Base runs, but the behavior remains otherwise well-defined.

44 Assume Base has a public virtual destructor. What is the status of this code?

CPP
Base* p = new Derived[2];
delete[] p;

Virtual destructors Hard
A. It destroys one Derived object and then releases the complete array allocation.
B. It is valid only when Base and Derived have identical object sizes.
C. It is valid because the virtual destructor recovers every derived array element.
D. It has undefined behavior because array deletion through a converted base pointer is invalid.

45 Which overload is selected by the call below?

CPP
void process(long);

template<class T>
void process(T);

process(1);

Compile-time polymorphism Hard
A. Both overloads, causing an ambiguity after integral conversion is considered.
B. process<int>(int), because it provides an exact parameter match.
C. process(long), because a non-template function always defeats a template.
D. Neither overload, because the template and non-template are equally specialized.

46 What does the following call select?

CPP
struct Base {
    void show(int);
};

struct Derived : Base {
    void show(double);
};

Derived d;
d.show(7);

Compile-time polymorphism Hard
A. Derived::show(double), because the derived declaration hides the base overload set.
B. The call is ill-formed because overloads cannot be distributed across class scopes.
C. Base::show(int), because its conversion sequence is an exact match.
D. The call is ambiguous because both inherited and declared functions participate.

47 What is printed by this code?

CPP
struct Base {
    virtual void print(int x = 1) { std::cout << "B" << x; }
};

struct Derived : Base {
    void print(int x = 2) override { std::cout << "D" << x; }
};

Base* p = new Derived;
p->print();
delete p;

Run-time polymorphism Hard
A. B2, because the dynamic default is combined with the statically selected function body.
B. B1, because omitting an argument disables virtual dispatch for the function call.
C. D1, because dispatch is dynamic but the default argument is selected statically.
D. D2, because both the function body and its default argument are selected dynamically.

48 Consider the access levels in this hierarchy:

CPP
struct Base {
    virtual void execute() { std::cout << "Base"; }
};

struct Derived : Base {
private:
    void execute() override { std::cout << "Derived"; }
};

Base* p = new Derived;
p->execute();



What happens?

Run-time polymorphism Hard
A. It prints Base; a private override is excluded from the virtual dispatch table.
B. It prints Derived; access is checked through Base, then virtual dispatch occurs.
C. It has undefined behavior because access levels differ across the override chain.
D. It fails to compile because the final overrider is private in the dynamic type.

49 What is printed while constructing and destroying Derived d?

CPP
struct Base {
    Base() { identify(); }
    virtual ~Base() { identify(); }
    virtual void identify() { std::cout << "B"; }
};

struct Derived : Base {
    Derived() { identify(); }
    ~Derived() override { identify(); }
    void identify() override { std::cout << "D"; }
};

Derived d;

Virtual functions Hard
A. BDDB, because dispatch is restricted to the currently constructed or destroyed class.
B. DBBD, because destruction changes the dynamic type before the derived destructor starts.
C. DDDD, because every call observes the complete object's most-derived dynamic type.
D. BDBD, because only constructor calls suppress dispatch to a derived override.

50 Given a virtual override, what does the explicitly qualified call do?

CPP
struct Base {
    virtual void f() { std::cout << "B"; }
};

struct Derived : Base {
    void f() override { std::cout << "D"; }
};

Base* p = new Derived;
p->Base::f();

Virtual functions Hard
A. It is ill-formed because virtual functions cannot be explicitly qualified.
B. It is ambiguous because both the qualified and final overrider are viable.
C. It prints B because explicit qualification suppresses virtual dispatch.
D. It prints D because the object still has Derived as its dynamic type.

51 Analyze this constructor:

CPP
class BufferPair {
    int* first;
    int* second;
public:
    BufferPair()
        : first(new int[100]), second(new int[200]) {}
    ~BufferPair() {
        delete[] first;
        delete[] second;
    }
};



What happens if allocation of second throws std::bad_alloc?

Dynamic constructors Hard
A. Both allocations are released because the compiler invokes BufferPair::~BufferPair.
B. The first allocation leaks because the complete object's destructor is not called.
C. Construction resumes with second == nullptr after the allocation exception is handled.
D. The first allocation is released because raw pointer members own their initializers.

52 Consider a class whose constructor allocates memory:

CPP
class Buffer {
    std::size_t size;
    int* data;
public:
    Buffer(std::size_t n) : size(n), data(new int[n]) {}
    ~Buffer() { delete[] data; }
};

Buffer a(10);
Buffer b = a;



With only the shown members, what is the central defect?

Dynamic constructors Hard
A. The implicit copy constructor allocates zero elements because size is copied after data.
B. The array is automatically reference-counted, so modifications unexpectedly affect both objects.
C. The destructor suppresses copying entirely, so the declaration of b is ill-formed.
D. The implicit copy constructor copies the pointer, so destruction can perform a double deletion.

53 Why does Derived remain abstract in this example?

CPP
struct Base {
    virtual void update(int) = 0;
};

struct Derived : Base {
    void update(double) {}
};

Abstract classes and concrete classes Hard
A. A pure virtual function can be implemented only outside the derived class definition.
B. A concrete derived class cannot change any parameter type of a member function.
C. Derived::update(double) overrides the function but preserves its pure status.
D. Derived::update(double) hides but does not override Base::update(int).

54 Consider:

CPP
struct Abstract {
    virtual void work() = 0;
};

void Abstract::work() {
    std::cout << "default";
}

struct Concrete : Abstract {
    void work() override {
        Abstract::work();
    }
};



Which statement is correct?

Abstract classes and concrete classes Hard
A. Concrete remains abstract because an override cannot call a pure virtual implementation.
B. The out-of-class definition is ill-formed because pure virtual functions cannot have bodies.
C. Abstract becomes concrete because every pure virtual function now has a definition.
D. Abstract remains abstract, while Concrete is concrete and may call the qualified definition.

55 Which declaration can represent a link to another object of the same class without making the class definition infinitely recursive?

Introduction to self-referential class Hard
A. struct Node { int value; const Node next; };
B. struct Node { int value; Node child[1]; };
C. struct Node { int value; Node next; };
D. struct Node { int value; Node* next; };

56 Consider this owning self-referential class:

CPP
struct Node {
    Node* next = nullptr;
    ~Node() { delete next; }
};

Node* a = new Node;
Node* b = new Node;
a->next = b;
b->next = a;
delete a;



What is the result?

Introduction to self-referential class Hard
A. Only a is destroyed, while b remains as a safely detached allocation.
B. The cyclic ownership causes recursive deletion and ultimately undefined behavior.
C. The cycle is detected by delete, so each node is destroyed exactly once.
D. Both nodes leak because destructors are skipped for objects participating in cycles.

57 What requirement applies to this pure virtual destructor?

CPP
struct Interface {
    virtual ~Interface() = 0;
};

struct Implementation : Interface {};

Pure virtual functions Hard
A. Interface::~Interface still needs a definition because derived destruction invokes it.
B. Interface::~Interface needs no definition because pure virtual functions are never invoked.
C. Implementation cannot be instantiated because a pure destructor cannot be overridden implicitly.
D. Interface becomes concrete once the compiler generates Implementation::~Implementation.

58 What is printed after object slicing occurs?

CPP
struct Base {
    virtual void identify() { std::cout << "B"; }
};

struct Derived : Base {
    void identify() override { std::cout << "D"; }
};

Derived d;
Base b = d;
b.identify();

Early binding and late binding Hard
A. B, because b is a separate sliced object whose dynamic type is Base.
B. D, because the virtual table from d is copied into the sliced base object.
C. D, because slicing removes data members but preserves the derived dynamic type.
D. B, because calls made with object syntax always use compile-time binding.

59 Which statement correctly distinguishes allocation failure from constructor failure?

CPP
Widget* p = new (std::nothrow) Widget;

Memory leaks and allocation failures Hard
A. Both failures terminate the program because std::nothrow disables exception handling.
B. Allocation failure throws std::bad_alloc, while constructor failure returns nullptr.
C. Both allocation failure and constructor failure are converted into a nullptr result.
D. Allocation failure returns nullptr, but an exception from Widget() can still propagate.

60 Assume process() may throw. Which implementation releases the allocated object on both normal and exceptional exits without an explicit try/catch?

CPP
void run() {
    // replacement code
}

Memory leaks and allocation failures Hard
A. auto p = std::make_unique<Resource>(); process(*p);
B. Resource* p = new Resource; delete p; process(*p);
C. Resource* p = new Resource; process(*p); p = nullptr;
D. Resource* p = new Resource; process(*p); delete p;