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. typedef
B. sizeof
C. new
D. delete

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

Dynamic memory allocation using new and delete operators Easy
A. remove(p);
B. free(p);
C. delete[] p;
D. delete 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. delete[] a;
C. free[] a;
D. clear[] a;

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

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

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

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

6 When is compile-time polymorphism resolved?

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

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

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

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

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

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

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

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

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

11 What does a dynamic constructor typically do?

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

12 Which operator is commonly used inside a dynamic constructor?

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

13 Which statement about an abstract class is correct?

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

14 What is a concrete class?

Abstract classes and concrete classes Easy
A. A class that cannot be inherited
B. A class with only static members
C. A class that can be instantiated
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. static void show() = 0;
B. virtual void show() = 1;
C. virtual void show() = 0;
D. void virtual = show();

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 immutable
C. The class becomes abstract
D. The class becomes a template

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

Early binding and late binding Easy
A. Dynamic binding
B. Late binding
C. Deferred 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. Early binding
B. Late binding
C. Static binding
D. Lexical 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 local variable leaves scope
D. A pointer is initialized to nullptr

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

Dynamic memory allocation using new and delete operators Medium
A. free(values);
B. values = nullptr;
C. delete[] 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 is a dangling pointer
B. It becomes nullptr automatically
C. It points to an integer containing 0
D. It owns a new copy of 25

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 constructor virtual
B. Make the derived constructor explicit
C. Make the base destructor virtual
D. Make the derived destructor static

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. delete new Derived;
C. Base* p = new Derived; delete p;
D. delete new Base;

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 function definition order
D. By the run-time type of the object

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

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

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. Both versions in declaration order
B. Neither version without a cast
C. Derived::show() through dynamic dispatch
D. Base::show() in every case

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

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

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

CPP
void process() override;

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

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. (&d)->display();
B. static_cast<Base&>(d).display();
C. d.display();
D. d.Base::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 class destructor
B. The copy constructor
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 performs a shallow pointer copy
C. It allocates an oversized array
D. It converts the pointer to void*

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

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

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

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

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

Introduction to self-referential class Medium
A. virtual Node next;
B. static Node next;
C. Node next;
D. 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. An uninitialized pointer value
C. The address of the final node
D. The address of the first node

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

Pure virtual functions Medium
A. virtual int calculate() == 0;
B. static int calculate() = 0;
C. virtual int calculate() = 0;
D. int calculate() override = 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 cannot define any constructors
B. B becomes a concrete class
C. B remains an abstract 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. The function selected at run time
B. The function from Derived
C. Both functions sequentially
D. The function from Base

40 Which call is resolved using late binding?

Early binding and late binding Medium
A. An overloaded function called with an integer
B. A static function called through a class name
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. p is a pointer value that may validly be passed to delete[].
B. p must be a null pointer because the requested array is empty.
C. delete[] p has undefined behavior because no elements were constructed.
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 causes a compile-time error because delete can detect every array allocation.
D. It is well-defined because int has a trivial destructor and no array cleanup is needed.

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

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 has undefined behavior because array deletion through a converted base pointer is invalid.
B. It destroys one Derived object and then releases the complete array allocation.
C. It is valid only when Base and Derived have identical object sizes.
D. It is valid because the virtual destructor recovers every derived array element.

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. process(long), because a non-template function always defeats a template.
B. Both overloads, causing an ambiguity after integral conversion is considered.
C. process<int>(int), because it provides an exact parameter match.
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. Base::show(int), because its conversion sequence is an exact match.
B. The call is ill-formed because overloads cannot be distributed across class scopes.
C. The call is ambiguous because both inherited and declared functions participate.
D. Derived::show(double), because the derived declaration hides the base overload set.

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. D1, because dispatch is dynamic but the default argument is selected statically.
B. B2, because the dynamic default is combined with the statically selected function body.
C. D2, because both the function body and its default argument are selected dynamically.
D. B1, because omitting an argument disables virtual dispatch for the function call.

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 Derived; access is checked through Base, then virtual dispatch occurs.
B. It fails to compile because the final overrider is private in the dynamic type.
C. It has undefined behavior because access levels differ across the override chain.
D. It prints Base; a private override is excluded from the virtual dispatch table.

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. BDBD, because only constructor calls suppress dispatch to a derived override.
B. BDDB, because dispatch is restricted to the currently constructed or destroyed class.
C. DBBD, because destruction changes the dynamic type before the derived destructor starts.
D. DDDD, because every call observes the complete object's most-derived dynamic type.

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 prints D because the object still has Derived as its dynamic type.
B. It is ill-formed because virtual functions cannot be explicitly qualified.
C. It prints B because explicit qualification suppresses virtual dispatch.
D. It is ambiguous because both the qualified and final overrider are viable.

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. Construction resumes with second == nullptr after the allocation exception is handled.
C. The first allocation leaks because the complete object's destructor is not called.
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 destructor suppresses copying entirely, so the declaration of b is ill-formed.
B. The implicit copy constructor allocates zero elements because size is copied after data.
C. The implicit copy constructor copies the pointer, so destruction can perform a double deletion.
D. The array is automatically reference-counted, so modifications unexpectedly affect both objects.

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. Derived::update(double) overrides the function but preserves its pure status.
B. Derived::update(double) hides but does not override Base::update(int).
C. A concrete derived class cannot change any parameter type of a member function.
D. A pure virtual function can be implemented only outside the derived class definition.

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. Abstract becomes concrete because every pure virtual function now has a definition.
B. The out-of-class definition is ill-formed because pure virtual functions cannot have bodies.
C. Concrete remains abstract because an override cannot call a pure virtual implementation.
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; Node child[1]; };
B. struct Node { int value; Node* next; };
C. struct Node { int value; Node next; };
D. struct Node { int value; const 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. The cycle is detected by delete, so each node is destroyed exactly once.
B. Both nodes leak because destructors are skipped for objects participating in cycles.
C. Only a is destroyed, while b remains as a safely detached allocation.
D. The cyclic ownership causes recursive deletion and ultimately undefined behavior.

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 becomes concrete once the compiler generates Implementation::~Implementation.
C. Implementation cannot be instantiated because a pure destructor cannot be overridden implicitly.
D. Interface::~Interface needs no definition because pure virtual functions are never invoked.

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. B, because calls made with object syntax always use compile-time binding.
D. D, because slicing removes data members but preserves the derived dynamic type.

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 returns nullptr, but an exception from Widget() can still propagate.
C. Both allocation failure and constructor failure are converted into a nullptr result.
D. Allocation failure throws std::bad_alloc, while constructor failure returns nullptr.

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. Resource* p = new Resource; delete p; process(*p);
B. Resource* p = new Resource; process(*p); p = nullptr;
C. auto p = std::make_unique<Resource>(); process(*p);
D. Resource* p = new Resource; process(*p); delete p;