Skip to main content

Embedded C: Double Pointers Explained

·625 words·3 mins
C Pointer Embedded
Table of Contents

Introduction
#

In embedded C, double pointers (char **) can be confusing, especially when combined with arrays. Different memory models behave differently, and understanding them is key to writing safe and efficient code.

We’ll go through three common memory models with examples, printing functions, and a practical sorting case.

1. Pointer Array (char *arr[])
#

// Define an array of pointers to strings
char *arr[] = {"abc", "def", "ghi"};

This creates an array where each element stores the address of a string literal.

Intermediate variable:

char *tmp = NULL;  // pointer to a string

Print function:

int printArray(char **srcArray, int count)
{
    if (srcArray == NULL) return -1;
    for (int i = 0; i < count; i++) {
        printf("%s\n", srcArray[i]);  // print each string
    }
    return 0;
}

2. Two-Dimensional Array (char arr[][])
#

// Define a 2D character array
char arr[3][5] = {"abc", "def", "ghi"};

This allocates 3 rows × 5 characters in contiguous memory.

Intermediate variable:

char tmp[5] = {0};  // buffer for a single row

Print function:

int printArray2D(char srcArray[][5], int count)
{
    if (srcArray == NULL) return -1;
    for (int i = 0; i < count; i++) {
        printf("%s\n", srcArray[i]);
    }
    return 0;
}

3. Dynamic Double Pointer (char **arr)
#

// Allocate memory for 100 string pointers
char **arr = (char **)malloc(100 * sizeof(char *));

// Allocate memory for each string
arr[0] = (char *)malloc(100 * sizeof(char));
arr[1] = (char *)malloc(100 * sizeof(char));
arr[2] = (char *)malloc(100 * sizeof(char));

// Copy strings into allocated memory
strcpy(arr[0], "abc");
strcpy(arr[1], "def");
strcpy(arr[2], "ghi");

Free memory:

for (int i = 0; i < 3; i++) {
    if (arr[i] != NULL)
        free(arr[i]);  // free each string
}
free(arr);  // free the pointer array itself

Intermediate variable:

char *tmp = NULL;  // temporary string pointer

Example: Sorting Strings with Double Pointers
#

// Copy strings from srcArray into new memory, then sort
char **sortArrayAndAlloc(const char **srcArray, int count, char *extra, int *outCount)
{
    // Allocate array of pointers
    char **outArray = (char **)malloc(count * sizeof(char *));
    if (srcArray == NULL || extra == NULL || outCount == NULL) {
        printf("Invalid parameters\n");
        return NULL;
    }

    *outCount = count;
    for (int i = 0; i < count; i++) {
        outArray[i] = (char *)malloc(50 * sizeof(char));  // allocate space for each string
        memset(outArray[i], 0, 50);
        strcpy(outArray[i], srcArray[i]);  // copy string
    }

    // Simple bubble sort by string comparison
    for (int i = 0; i < count; i++) {
        for (int j = i + 1; j < count; j++) {
            if (strcmp(outArray[i], outArray[j]) > 0) {
                char *tmp = outArray[i];
                outArray[i] = outArray[j];
                outArray[j] = tmp;
            }
        }
    }

    return outArray;
}

Usage:

int main()
{
    char *srcArray[] = {"bbbbb", "aaaaa", "cccccc"};
    char *extra = "111111111111";  // unused in this example
    int outCount = 0;

    // Get sorted array
    char **sortedArray = sortArrayAndAlloc(srcArray, 3, extra, &outCount);

    // Print and free
    for (int i = 0; i < outCount; i++) {
        printf("%s\n", sortedArray[i]);
        free(sortedArray[i]);  // free each string
    }
    free(sortedArray);  // free pointer array

    return 0;
}

Utility Functions
#

// Allocate memory for an array of strings
int allocArray(char ***outArray, int count)
{
    char **tmp = (char **)malloc(count * sizeof(char *));
    for (int i = 0; i < count; i++) {
        tmp[i] = (char *)malloc(100 * sizeof(char));  // each string can hold 100 chars
    }
    *outArray = tmp;
    return 0;
}

// Free memory for an array of strings
int freeArray(char ***outArray, int count)
{
    char **p = *outArray;
    for (int i = 0; i < count; i++) {
        free(p[i]);
    }
    free(p);
    *outArray = NULL;
    return 0;
}

Summary
#

  • Pointer array (char *arr[]) → array of string pointers.
  • 2D array (char arr[][]) → fixed-size, contiguous memory.
  • Dynamic double pointer (char **arr) → flexible, requires manual memory management.

Related

Debugging Memory Overwrite Issues in Embedded C
·601 words·3 mins
C Embedded Memory Debugging
嵌入式 C 程序的内聚和耦合
·306 words·2 mins
程序 C Cohesion Coupling Embedded
C Function Pointers Explained with Examples
·606 words·3 mins
C Function Pointer Programming