Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Fundamental Concepts of Memory and Pointers in C

Tech Aug 14 18

Memory and Address

Memory Units

Computer memory serves as the primary storage for data during program execution. When the CPU processes information, it retrieves data from and stores results back into memory. To manage and access this vast storage efficiently, memory is organized into discrete units, analogous to individual rooms in a building.

Each memory unit occupies one byte, which is equivalent to eight binary bits. Every byte is assigned a unique numerical identifier. This identifier is known as an address. In C programming, the term pointer is synonymous with this address.

Memory Addressing Mechanism

Computer hardware components interact via electrical pathways. The CPU locates a specific byte in memory by sending its address via the address bus. To read or write data, the CPU issues a command via the control bus. The data is then transferred between the CPU and memory over the data bus.

For a CPU to access a byte, it must know that byte's precise location. Memory addressing provides this capability. In a 32-bit system, the address bus consists of 32 lines. Each line can transmit a binary 1 or 0 signal, enabling the bus to represent 2^32 unique addresses. When the CPU sends an address, the memory unit at that location responds by placing its data on the data bus for transfer.

Pointer Variables and Address Operations

The Address-of Operator (&)

Variable declaration in C requests a memory allocation.

int primary_value = 10;

This statement allocates four consecutive bytes of memory to store the integer primary_value. Each byte has its own address. The & operator extracts the starting address (the smallest address) of the variable's memory block.

#include <stdio.h>
int main() {
    int primary_value = 10;
    printf("Address: %p\n", &primary_value);
    return 0;
}

Knowing the first byte's address allows access to the entire variable's data.

Pointer Variables and the Dereference Operator

Storing Addresses

An address retrieved by & can be stored in a specialized variable known as a pointer variable.

#include <stdio.h>
int main() {
    int primary_value = 10;
    int *value_ptr = &primary_value; // Store address in pointer
    return 0;
}

A pointer variable holds memory addresses. Its type (e.g., int *) indicates it points to data of a specific type.

Type Decomposition

The declaration int *value_ptr can be interpreted in two parts:

  1. The * denotes value_ptr is a pointer variable.
  2. The int specifies it points to an integer.

The Dereference Operator (*)

The dereference operator (*) accesses the value stored at the address held by a pointer.

#include <stdio.h>
int main() {
    int primary_value = 10;
    int *value_ptr = &primary_value;
    *value_ptr = 20; // Changes primary_value to 20
    return 0;
}

The expression *value_ptr is equivalent to accessing the variable primary_value directly.

Size of Pointer Variables

A pointer's size is determined by the system's addressing scheme, not the type of data it points to.

  • On a 32-bit platform, an address is 32 bits (4 bytes).
  • On a 64-bit platform, an address is 64 bits (8 bytes).
#include <stdio.h>
int main() {
    printf("%zu\n", sizeof(char*));
    printf("%zu\n", sizeof(int*));
    printf("%zu\n", sizeof(double*));
    return 0;
}

All pointer variables on the same platform will yield the same size from sizeof.

Significance of Pointer Variable Types

Pointer Dereferencing Scope

A pointer's type dictates how many bytes are accessed during dereferencing.

#include <stdio.h>
int main() {
    int data = 0x11223344;
    int *int_ptr = &data;
    *int_ptr = 0; // Modifies all 4 bytes
    return 0;
}
#include <stdio.h>
int main() {
    int data = 0x11223344;
    char *char_ptr = (char*)&data;
    *char_ptr = 0; // Modifies only 1 byte
    return 0;
}

An int* pointer has permission to manipulate four bytes, while a char* pointer can only affect one byte.

Pointer Arithmetic

Adding an integer to a pointer moves it forward in memory by a number of bytes equal to the size of the data type it points to.

#include <stdio.h>
int main() {
    int n = 10;
    char *c_ptr = (char*)&n;
    int *i_ptr = &n;
    printf("c_ptr     = %p\n", c_ptr);
    printf("c_ptr + 1 = %p\n", c_ptr + 1); // Advances 1 byte
    printf("i_ptr     = %p\n", i_ptr);
    printf("i_ptr + 1 = %p\n", i_ptr + 1); // Advances 4 bytes
    return 0;
}

The type of a pointer determines the stride size for increment (+) or decrement (-) operations.

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.