Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Understanding C Arrays and Pointers: Size, Memory Allocation, and sizeof Behavior

Tech May 10 2

Three Ways to Define Arrays in C

Array definition in C can be achieved through three distinct approaches, each with different characteristics regarding size determination, memory location, and lifetime.

Fixed-Size Arrays

Array size is determined at compile time:

#include <stdio.h>

int main() {
    int data[5] = {10};
    printf("Size: %zu bytes\n", sizeof(data));
    return 0;
}

Memory resides on the stack. When the enclosing function returns, the array is automatically destroyed. Stack-allocated arrays are suitable for small, predictable data sets.

Variable-Length Arrays (VLA)

C99 introduced VLAs where dimensions are determined at runtime:

#include <stdio.h>

int main() {
    int size;
    printf("Enter array size: ");
    scanf("%d", &size);
    
    int buffer[size];
    printf("Array occupies %zu bytes\n", sizeof(buffer));
    return 0;
}

VLAs remain on the stack, meaning available space is typically limited compared to heap memory. When the function exits, VLA storage is reclaimed automatically.

C11 Note: Variable-length arrays became an optional feature. Compiler support varies—GCC enables them by default while Clang may restrict or disable them. Portability concerns exist when relying on VLAs.

Dynamic Memory Allocation

Using malloc for runtime-sized arrays:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int count = 8;
    int *heapArray = (int*)malloc(count * sizeof(int));
    
    if (heapArray == NULL) {
        return 1;
    }
    
    printf("Pointer size: %zu bytes\n", sizeof(heapArray));
    free(heapArray);
    return 0;
}

Memory comes from the heap, which offers substantially more capacity than the stack. This allocation persists until explicitly released via free(). The programmer bears full responssibility for deallocation—failing to release memory results in leaks that accumulate over time.

Memory Leak: When progarms allocate memory via malloc, calloc, or realloc without corresponding free calls, the memory remains reserved even after the data becomes unnecessary. These orphaned blocks gradually consume available memory, degrading performance and potentially causing crashes.

The sizeof Trap with Dynamic Arrays

A critical misconception involves using sizeof on dynamically allocated arrays:

int *ptr = (int*)malloc(10 * sizeof(int));
int len = sizeof(ptr) / sizeof(int);  // WRONG: returns pointer size, not element count

The variable ptr is a pointer, not an array. sizeof(ptr) yields the pointer's size (typically 8 bytes on 64-bit systems), not the allocated buffer's size. The division 8 / 4 incorrectly produces 2 instead of 10.

Why sizeof Works on VLAs but Not on malloc Pointers

For static and variable-length arrays, the compiler knows the exact dimensions. The array name acts like a constant pointer to the first element, but crucially, the compiler retains size information. Thus sizeof(array) returns the complete array size.

For dynamically allocated memory, malloc returns a raw pointer. The compiler has no knowledge of the allocated extent—only the address. Consequently, sizeof on a malloc'd pointer reports the pointer itself, not the buffer it references.

#include <stdio.h>

int main() {
    int vla[6];
    int *dynamic = (int*)malloc(6 * sizeof(int));
    
    printf("VLA sizeof: %zu (full array)\n", sizeof(vla));
    printf("malloc pointer sizeof: %zu (pointer only)\n", sizeof(dynamic));
    
    free(dynamic);
    return 0;
}

Practical consequence: When using dynamic allocation, you must track length separately or use structures that embed size metadata.

Finding Prime Numbers: A Practical Example

The following problem—adapted from Google's recruitment challenges—demonstrates array manipulation and prime checking:

Problem: Given an integer N and digit count K, find the first K-digit prime number appearing consecutively within N. Output "404" if none exists.

#include <stdio.h>
#include <stdbool.h>
#include <math.h>

bool checkPrime(int n) {
    if (n < 2) return false;
    for (int i = 2; i <= (int)sqrt(n); i++) {
        if (n % i == 0) return false;
    }
    return true;
}

int main() {
    int totalDigits, digitCount, digit;
    int digits[1000];
    
    scanf("%d %d", &totalDigits, &digitCount);
    
    for (int i = 0; i < totalDigits; i++) {
        scanf("%1d", &digit);
        digits[i] = digit;
    }
    
    int endPosition = totalDigits - digitCount;
    
    for (int start = 0; start <= endPosition; start++) {
        int value = 0;
        int exponent = digitCount - 1;
        
        for (int offset = 0; offset < digitCount; offset++) {
            value += digits[start + offset] * (int)pow(10, exponent);
            exponent--;
        }
        
        if (checkPrime(value)) {
            printf("%0*d\n", digitCount, value);
            return 0;
        }
    }
    
    printf("404\n");
    return 0;
}

Key technique: %0*d uses * as a dynamic width specifier. The 0 flag pads with zeros, * substitutes the first argument for width, and d specifies integer output. This ensures K-digit numbers display correctly even when leading digit are zero.

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.