Unit4 - Subjective Questions
CSE357 • Practice Questions with Detailed Answers
Compare and contrast C, C++, and Java with respect to programming paradigms, memory management, and platform dependency.
Comparison of C, C++, and Java:
| Feature | C | C++ | Java |
|---|---|---|---|
| Paradigm | Procedural / Structure Oriented. | Multi-paradigm (Procedural + Object-Oriented). | Pure Object-Oriented (mostly). |
| Platform Dependency | Platform Dependent (compiled code runs on specific OS). | Platform Dependent. | Platform Independent (Write Once, Run Anywhere via JVM). |
| Memory Management | Manual (using malloc, calloc, free). |
Manual (using new, delete). |
Automatic (Garbage Collection). |
| Pointers | Supported (robust pointer arithmetic). | Supported (pointers + references). | Not supported explicitly (references used internally). |
| Inheritance | Not supported. | Supported (Multiple inheritance allowed). | Supported (Multiple inheritance via Interfaces only). |
Explain the concept of Pointers in C/C++. How is the address-of operator (\&) different from the dereference operator (*)?
Pointers are variables that store the memory address of another variable. They enable direct memory access and manipulation.
Difference between operators:
-
Address-of Operator ():
- It is a unary operator that returns the memory address of a variable.
- Example: If integer is stored at memory location $1000$, then evaluates to $1000$.
-
Dereference Operator ():
- It is a unary operator used to access the value stored at the address held by the pointer.
- Example: If holds the address $1000$, then gives the value stored at that address.
Syntax Example:
c
int x = 10;
int ptr = &x; // ptr holds address of x
printf("%d", ptr); // Prints 10
Define Pointer Arithmetic. If an integer pointer holds the address $1000$ and the size of an integer is 4 bytes, what will be the value of ? Explain the calculation.
Pointer Arithmetic refers to the set of valid arithmetic operations (addition, subtraction) that can be performed on pointers. When arithmetic is performed on a pointer, the address changes based on the data type size the pointer points to.
Calculation:
The formula for pointer addition is:
Given:
- Current Address () = $1000$
- Increment () = $2$
- Size of
int= $4$ bytes
Result: The new address will be 1008.
Describe the four distinct Storage Classes in C/C++ and their scope, lifetime, and default initial values.
The four storage classes describe the visibility (scope) and lifetime of variables:
-
auto (Automatic):
- Scope: Local to the block/function.
- Lifetime: Exists only while the block is executing.
- Default Value: Garbage value.
- Storage: Stack.
-
register:
- Scope: Local.
- Lifetime: Within the block.
- Default Value: Garbage value.
- Storage: CPU Registers (for faster access).
-
static:
- Scope: Local (visibility) but persists between function calls.
- Lifetime: Throughout the program execution.
- Default Value: Zero ($0$).
- Storage: Data Segment.
-
extern:
- Scope: Global (visible to all files).
- Lifetime: Throughout the program execution.
- Default Value: Zero ($0$).
- Storage: Data Segment.
Differentiate between a Class and a Structure in the context of C++.
While both Classes and Structures are user-defined data types used to group variables, they differ primarily in their default access mechanisms in C++:
-
Default Access Specifier:
- Structure (
struct): Members are public by default. If you do not specify private or protected, anyone can access the members. - Class (
class): Members are private by default. Data hiding is enforced automatically unless specified otherwise.
- Structure (
-
Usage Context:
- Struct: Generally used for grouping plain data elements (POD - Plain Old Data).
- Class: Used for full Object-Oriented Programming involving data encapsulation, inheritance, and polymorphism.
-
Inheritance:
- When deriving from a struct, the default mode is public. When deriving from a class, the default mode is private.
Explain the four pillars of Object-Oriented Programming (OOP).
The four pillars of OOP are:
-
Encapsulation:
- The bundling of data (variables) and methods (functions) that operate on that data into a single unit (Class). It also involves restricting direct access to some of an object's components (Data Hiding).
-
Abstraction:
- Hiding the complex implementation details and showing only the essential features of the object. For example, a user knows how to use a car brake but doesn't need to know the internal hydraulics.
-
Inheritance:
- The mechanism by which one class (Child/Derived) acquires the properties and behaviors of another class (Parent/Base). It promotes code reusability.
-
Polymorphism:
- The ability of a message or function to be displayed in more than one form. It allows objects to be treated as instances of their parent class rather than their actual class. Types include compile-time (overloading) and run-time (overriding).
Discuss the concept of Constructors and Destructors in C++. When are they invoked?
Constructor:
- A special member function with the same name as the class.
- It has no return type (not even void).
- Invocation: It is automatically called when an object of the class is created.
- Purpose: To initialize the object's member variables and allocate resources.
Destructor:
- A special member function with the same name as the class preceded by a tilde ().
- It takes no arguments and has no return type.
- Invocation: It is automatically called when an object goes out of scope or is explicitly deleted.
- Purpose: To release resources (like memory or file handles) allocated to the object.
Compare Call by Value and Call by Reference with appropriate examples.
Call by Value:
- A copy of the actual parameter's value is passed to the formal parameter.
- Changes made inside the function do not reflect in the original variable.
- Memory: Separate memory is allocated for formal parameters.
- Example:
void func(int x)called asfunc(a).
Call by Reference:
- The reference (address/alias) of the actual parameter is passed.
- Changes made inside the function are reflected in the original variable.
- Memory: Formal parameter is just an alias; no new storage for the value.
- Example (C++):
void func(int &x)called asfunc(a).
| Summary Table: | Feature | Call by Value | Call by Reference |
|---|---|---|---|
| Data Safety | Original data is safe. | Original data can be modified. | |
| Performance | Slower for large objects (copying overhead). | Faster (no copying). |
What is Binding? Distinguish between Static Binding and Dynamic Binding.
Binding refers to the process of associating a function call with the actual function definition (code segment).
1. Static Binding (Early Binding):
- Time: Occurs at Compile Time.
- The compiler knows exactly which function to call.
- Efficiency: Faster execution as there is no runtime overhead.
- Examples: Normal function calls, Function Overloading, Operator Overloading.
2. Dynamic Binding (Late Binding):
- Time: Occurs at Runtime.
- The specific function to be called is determined while the program is running, usually based on the type of the object.
- Efficiency: Slower due to the lookup mechanism (e.g., v-tables in C++).
- Examples: Virtual functions in C++, Method Overriding in Java.
Explain the difference between Stack and Heap memory in the context of OOP languages.
Stack Memory:
- Allocation: Static memory allocation.
- Management: Managed automatically by the OS/Compiler (LIFO structure).
- Usage: Stores local variables, function parameters, and return addresses.
- Speed: Very fast access.
- Limit: Size is limited (Stack overflow can occur).
Heap Memory:
- Allocation: Dynamic memory allocation.
- Management: Managed manually by the programmer (C++) or Garbage Collector (Java).
- Usage: Stores objects and variables whose size or lifetime is not known at compile time.
- Speed: Slower compared to stack (due to allocation/deallocation overhead).
- Limit: Limited by the size of virtual memory (much larger than stack).
How is dynamic memory management handled in C++ versus C? Compare new/delete with malloc/free.
C uses library functions for memory management, while C++ uses operators.
Comparison:
| Feature | malloc / free (C) |
new / delete (C++) |
|---|---|---|
| Type | Functions (part of stdlib.h). |
Operators (built-in). |
| Constructors | Does not call constructors. | Calls constructors upon allocation. |
| Destructors | Does not call destructors. | Calls destructors upon deletion. |
| Return Type | Returns void* (needs casting). |
Returns exact data type pointer (type-safe). |
| Size Calculation | Requires manual size calculation (sizeof). |
Size calculated automatically by compiler. |
| Failure | Returns NULL. |
Throws std::bad_alloc exception. |
What is Garbage Collection in Java? Briefly explain the concept of 'Reachability'.
Garbage Collection (GC) is an automatic memory management process in Java. It identifies and deletes objects that are no longer needed by the program to reclaim heap memory resources.
How it works:
- The JVM (Java Virtual Machine) runs a daemon thread called the Garbage Collector.
- Programmers do not explicitly delete objects (no
deletekeyword).
Concept of Reachability:
- GC relies on the concept of Reachability to determine if an object is 'live' or 'garbage'.
- Reachable Object: An object is reachable if it is referenced by a root node (e.g., local variables on the stack, static variables) or by another reachable object.
- Unreachable Object: If there is no chain of references connecting an object to the GC Roots, it is considered unreachable and eligible for garbage collection.
Explain the concept of Virtual Functions in C++. Why are they necessary for runtime polymorphism?
Virtual Functions:
- A virtual function is a member function declared within a base class and redefined (overridden) by a derived class.
- It is declared using the
virtualkeyword.
Necessity for Runtime Polymorphism:
- In C++, pointers to a base class can point to derived class objects.
- Without
virtual, the compiler uses Static Binding. If you call a function using a base class pointer, the base class version is called, even if the object is actually a derived class instance. - With
virtual, the compiler uses Dynamic Binding. It checks the actual type of the object at runtime and calls the derived class version of the function.
Example:
cpp
Base *b = new Derived();
b->show(); // Calls Derived::show() only if Base::show() is virtual
What is the this pointer in C++? What is its significance?
The this pointer is an implicit pointer available inside non-static member functions of a class. It points to the object for which the member function is currently executing.
Significance & Uses:
-
Distinguishing Parameters: When local variable names (parameters) match member variable names,
this->variableallows access to the member variable.
cpp
void setX(int x) { this->x = x; } -
Chaining Calls: It enables method chaining by returning the current object reference (
return *this;). -
Passing Object: It allows an object to pass its own address to other functions.
Distinguish between Shallow Copy and Deep Copy in the context of memory handling.
Shallow Copy:
- Copies all member field values from one object to another.
- If a member is a pointer, only the memory address is copied, not the data it points to.
- Issue: Both objects point to the same memory location. If one object modifies the data or frees the memory, the other object is affected (leads to dangling pointers).
- Default behavior of copy constructors.
Deep Copy:
- Copies all fields, but for pointers, it allocates new memory and copies the actual data pointed to.
- Result: The two objects are completely independent.
- Requirement: Must be implemented manually (user-defined copy constructor) when the class manages dynamic memory.
What is a Memory Leak? Provide a C++ code snippet that would cause a memory leak and explain how to fix it.
Memory Leak:
A memory leak occurs when a program allocates memory dynamically (in the Heap) but fails to deallocate it after use. Over time, this consumes available memory, potentially causing the program or system to crash.
Problematic Code:
cpp
void createLeak() {
int *ptr = new int[100]; // Allocate memory
// ... use ptr ...
// Function ends, ptr goes out of scope
// BUT 'delete[] ptr' was never called.
}
In this example, the pointer ptr (stack) is destroyed, but the 100 integers (heap) remain allocated with no way to access or free them.
Fix:
Explicitly release the memory before the pointer goes out of scope:
cpp
delete[] ptr;
Define Access Specifiers in OOP. Explain public, private, and protected.
Access Specifiers determine the visibility and accessibility of class members (variables and functions).
-
Public:
- Members are accessible from anywhere in the program (inside the class, derived classes, and outside via object instances).
- Used for the interface of the class.
-
Private:
- Members are accessible only within the class defining them.
- They are hidden from derived classes and the outside world.
- Used for data hiding (Encapsulation).
-
Protected:
- Members are accessible within the class defining them and in derived classes (child classes).
- They remain inaccessible to the outside world.
- Used specifically to support inheritance while maintaining encapsulation.
What is a Reference in C++? How does it differ from a pointer regarding initialization and nullability?
A Reference is an alias for an existing variable. It is a name that acts as another label for a memory location.
Differences from Pointers:
-
Initialization:
- Reference: Must be initialized when declared. It cannot exist without being bound to a variable.
int &ref = x; // Valid
int &ref; // Invalid - Pointer: Can be declared without initialization.
- Reference: Must be initialized when declared. It cannot exist without being bound to a variable.
-
Nullability:
- Reference: Cannot be
NULL. It must always refer to a valid object. - Pointer: Can be
NULL(nullptr).
- Reference: Cannot be
-
Reassignment:
- Reference: Cannot be reseated to refer to another variable once initialized.
- Pointer: Can be reassigned to point to different variables.
Explain the concept of Friend Functions in C++. Why does it seemingly violate encapsulation, and when is it useful?
Friend Function:
- A friend function is a non-member function that is granted access to the
privateandprotectedmembers of a class. - It is declared inside the class with the keyword
friend.
Violation of Encapsulation:
- Strict OOP states that private data should only be accessed by the class's own methods. Friend functions break this rule by allowing external functions to touch private data, theoretically weakening the security boundary.
Utility:
- It is useful for Operator Overloading (e.g., overloading
<<forcout, which requires access to class internals but is a standard library function). - It allows two different classes to share private data efficiently without exposing that data to the entire world via public getters/setters.
Derive the logic for Pass by Address (Pointer) in C by writing a function to swap two integers. Explain the memory operations involved.
Logic:
To swap variables defined in the main function using a separate function, we must pass the addresses of the variables. The function receives pointers, dereferences them to access the original memory locations, and swaps the values.
Code:
c
void swap(int a, int b) {
int temp = a; // Store value at address 'a' in temp
a = b; // Copy value at address 'b' to address 'a'
b = temp; // Copy temp to address 'b'
}
int main() {
int x = 5, y = 10;
swap(&x, &y);
// x is now 10, y is now 5
}
Memory Operations:
mainallocatesxandyon the stack.swapis called; the addresses (e.g.,0x100,0x104) are passed to pointersaandb.*aaccesses memory at0x100directly. The modification happens inmain's stack frame, notswap's local copy.