Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

C++ Core Programming: Memory Management, References and OOP Fundamentals

Tech 1

Memory Layout in C++

  • Code Area: Stores binary code of functions managed by the operating system
  • Global Area: Holds global variables, static variables, and constents
  • Stack Area: Automatically allocated and deallocated by compiler for function parameters and local variables
  • Heap Area: Manually managed by programmer for dynamic allocation

Pre-execution Memory Segments

Before program execution, the executable contains two main segments:

Code Segment: Contains machine instructions. It's shared among processes and read-only to prevent accidental modification.

Global Segment: Stores global and static variables along with constants like string literals.

Example:

int global_var = 10;
const int const_global = 20;

int main() {
    int local_var = 30;
    static int static_var = 40;
    
    cout << "Local var address: " << &local_var << endl;
    cout << "Global var address: " << &global_var << endl;
    cout << "Static var address: " << &static_var << endl;
    cout << "Const global address: " << &const_global << endl;
    
    return 0;
}

Runtime Memory Areas

Stack Area: Automatic management by compiler for local variables and function parameters.

Important Note: Never return addresses of local variables as they're automatically released.

int* getLocalAddress() {
    int local = 42;
    return &local; // Dangerous!
}

int main() {
    int* ptr = getLocalAddress();
    cout << *ptr << endl; // Undefined behavior
    return 0;
}

Heap Area: Manual allocation/deallocation required. Uses new operator.

int* createOnHeap() {
    return new int(100);
}

int main() {
    int* ptr = createOnHeap();
    cout << *ptr << endl;
    delete ptr;
    return 0;
}

Reference Mechanism

Basic Usage

References provide alternative names for existing variables:

int value = 42;
int& alias = value; // Create reference

alias = 100; // Modifies original variable
cout << value << endl; // Outputs 100

Key Rules

  • References must be initialized at declaration
  • Cannot be reassigned after initialization
int a = 10;
int& ref = a; // Must initialize

int b = 20;
ref = b; // Assignment, not reassignment

Function Parameters

References enable modifying actual parameters:

void swap(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 10, y = 20;
    swap(x, y);
    cout << x << " " << y << endl; // Outputs 20 10
    return 0;
}

Return Values

Functions can return references (but avoid returning local variables):

int& getReference() {
    static int value = 42;
    return value;
}

int main() {
    int& ref = getReference();
    ref = 100; // Modifies static variable
    cout << ref << endl; // Outputs 100
    return 0;
}

Function Overloading

Default Parameters

Function parameters can have default values:

int calculate(int a, int b = 10, int c = 20) {
    return a + b + c;
}

int main() {
    cout << calculate(5) << endl; // Uses defaults
    return 0;
}

Function Overloading

Multiple functions with same name but different signatures:

void process(int x) {}
void process(double x) {}
void process(int x, double y) {}

int main() {
    process(10);
    process(3.14);
    process(5, 2.5);
    return 0;
}

Object-Orientde Programming

Class Design

Classes encapsulate data and behavior:

class Student {
public:
    string name;
    string id;
    
    void display() {
        cout << "Name: " << name << " ID: " << id << endl;
    }
    
    void setName(string n) { name = n; }
    void setId(string i) { id = i; }
};

int main() {
    Student s1;
    s1.setName("Alice");
    s1.setId("001");
    s1.display();
    return 0;
}

Access Control

Three access levels:

  • public: Accessible from anywhere
  • protected: Accessible within class and derived classes
  • private: Accessible only within class
class Person {
public:
    string name;
protected:
    string car;
private:
    int id;
};

int main() {
    Person p;
    p.name = "John"; // OK
    // p.car = "BMW"; // Error - protected
    return 0;
}

Constructor and Destructor

class Person {
public:
    Person() { cout << "Constructor called" << endl; }
    ~Person() { cout << "Destructor called" << endl; }
};

int main() {
    Person p; // Constructor called
    return 0; // Destructor called
}

Copy Constructor

class Person {
public:
    Person(const Person& other) {
        // Deep copy implementation
        age = other.age;
    }
};

Operator Overloading

Arithmetic Operators

class Vector {
public:
    int x, y;
    
    Vector operator+(const Vector& other) {
        Vector result;
        result.x = x + other.x;
        result.y = y + other.y;
        return result;
    }
};

Stream Operators

ostream& operator<<(ostream& out, const Vector& v) {
    out << "(" << v.x << ", " << v.y << ")";
    return out;
}

Increment Operators

Vector& operator++() { // Prefix
    x++;
    y++;
    return *this;
}

Vector operator++(int) { // Postfix
    Vector temp = *this;
    x++;
    y++;
    return temp;
}

Inheritance

Basic Syntax

class Base {
public:
    virtual void display() { cout << "Base" << endl; }
};

class Derived : public Base {
public:
    void display() override { cout << "Derived" << endl; }
};

Virtual Functions

class Animal {
public:
    virtual void speak() { cout << "Animal speaks" << endl; }
};

class Dog : public Animal {
public:
    void speak() override { cout << "Dog barks" << endl; }
};

void makeSound(Animal& animal) {
    animal.speak(); // Dynamic binding
}

File Operations

Text Files

// Writing
ofstream outFile("data.txt");
outFile << "Hello World" << endl;
outFile.close();

// Reading
ifstream inFile("data.txt");
string line;
while (getline(inFile, line)) {
    cout << line << endl;
}
inFile.close();

Binary Files

struct Data {
    int id;
    char name[32];
};

// Writing
ofstream file("data.bin", ios::binary);
Data d = {1, "John"};
file.write(reinterpret_cast<char*>(&d), sizeof(d));
file.close();

// Reading
ifstream readFile("data.bin", ios::binary);
Data readData;
readFile.read(reinterpret_cast<char*>(&readData), sizeof(readData));
readFile.close();

Advanced Concepts

Pure Virtual Functions

class AbstractClass {
public:
    virtual void pureFunction() = 0; // Pure virtual
};

class ConcreteClass : public AbstractClass {
public:
    void pureFunction() override { cout << "Implementation" << endl; }
};

Virtual Destructors

class Base {
public:
    virtual ~Base() { /* Cleanup */ }
};

File Stream Modes

  • ios::in: Read mode
  • ios::out: Write mode
  • ios::binary: Binary mode
  • ios::app: Append mode
  • ios::trunc: Truncate existing file

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.