Near, Far, and Huge Pointers in C: Understanding Memory Models

Discover the significance of near, far, and huge pointers in C, used in 16-bit Intel architectures for memory management. Learn how these pointers functioned within the segmented memory model of early computing systems, and understand why they are now largely obsolete in modern environments.



Near, Far, and Huge Pointers in C

The concepts of near pointers, far pointers, and huge pointers were prevalent in the C programming language for handling segmented memory models. However, these concepts have become largely obsolete in modern computing environments due to advancements in CPU architecture.

These pointer types were primarily implemented in 16-bit Intel architectures during the era of the MS-DOS operating system.

Near Pointer

The near keyword in C is used to declare a pointer that can only access memory within the current data segment. A near pointer on a 16-bit machine can store only 16-bit addresses.

The main limitation of a near pointer is its ability to access only about 64 KB of data at a time. The size of a near pointer is 2 bytes.

Syntax of Near Pointer


 near 
 near 

The following statement declares a near pointer for the variable ptr:

char near *ptr;

Example of Near Pointer

Here’s an example that illustrates the use of a near pointer:

Syntax

#include 

int main(){
    // Declaring a near pointer
    int near *ptr;

    // Size of the near pointer
    printf("Size of Near Pointer: %d bytes", sizeof(ptr));
    
    return 0;
}
        
Output

Size of Near Pointer: 2 bytes
        

Far Pointer

A far pointer is a 32-bit pointer that can access memory outside the current data segment. This type of pointer requires a "sector register" to store data addresses in the segment, as well as another sector register to reference the most recent sector.

A far pointer stores both the offset and segment addresses. When the pointer is incremented or decremented, only the offset portion changes. The size of a far pointer is 4 bytes.

Syntax of Far Pointer


 far 
 far 

The following statement declares a far pointer for the variable ptr:

char far *s;

Example of Far Pointer

Here’s an example that illustrates the use of a far pointer:

Syntax

#include 

int main(){
    int number = 50;
    int far *p;

    p = &number;
    printf("Size of far pointer: %d bytes", sizeof(number));

    return 0;
}
        
Output

Size of far pointer: 4 bytes
        

Huge Pointer

A huge pointer, like a far pointer, is also 32 bits in size. It can access memory locations that are outside the current sector. Unlike far pointers, which are fixed, huge pointers can be modified.

In a huge pointer, both the offset and segment addresses can change, allowing the pointer to jump between different segments. Huge pointers compare absolute addresses, enabling relational operations. The size of a huge pointer is 4 bytes.

Syntax of Huge Pointer


data_type huge *pointer_name;

Example of Huge Pointer

Here’s an example that illustrates the use of a huge pointer:

Syntax

#include 

int main(){
    int huge *ptr;
    printf("Size of the Huge Pointer: %d bytes", sizeof(ptr));

    return 0;
}
        
Output

Size of Huge Pointer: 4 bytes
        

Pointers to Remember

Keep the following points in mind when working with near, far, and huge pointers:

  • A near pointer can only store addresses up to the first 64 KB, while a far pointer can store addresses for any memory location in RAM. A huge pointer can move between multiple memory segments.
  • A near pointer uses a single register to store addresses, whereas a far pointer uses two registers (segment and offset addresses). The size of a near pointer is 2 bytes, while both far and huge pointers are 4 bytes.
  • Two far pointer values can point to the same location, but this is not possible with huge pointers.
  • Near, far, and huge pointers were utilized to manage memory access based on segment registers in segmented memory architectures. Modern systems use flat memory models, addressing memory as a single contiguous space. Current C compilers offer better memory management techniques that do not rely on segmentation concepts.