MrDB MrDB - 28 days ago 18
C Question

Dynamic memory/realloc string array

Looking to create a dynamic array of string values.

In the example code below, the intention was for a new array item to be added (realloc) and a new string ("string 3") to be added to the array at runtime.

I imagine the issue is either improper use of pointers and/or something wrong with the realloc logic?

Appreciate any help.

The actual output I'm getting:

Before:
Array[0]: string 1
Array[1]: string 2
After:
Array[0]: string 1
Array[1]: string 2


The code:

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

char **myArray;

main(int argc, char *argv[])
{
int i = 0;
myArray = malloc(2 * sizeof(char*));
int arrayIndexs = sizeof(*myArray) / sizeof(char*);

//Allocate memory for each [x]
for (i = 0; i <= arrayIndexs; i++)
myArray[i] = malloc(254 * sizeof(char*));
//Populate initial values
if(myArray != NULL)
{
strcpy(myArray[0], "string 1");
strcpy(myArray[1], "string 2");
}
//Print out array values
printf("Before: \n");
for (i = 0; i <= arrayIndexs; i++)
printf("Array[%d]: %s\n",i, myArray[i]);

//Expand array to allow one additional item in the array
myArray = (char **)realloc(myArray, sizeof(myArray)*sizeof(char*));

//Allocate memory for the new string item in the array
myArray[arrayIndexs+1] = malloc(254 * sizeof(char*));

//Populate a new value in the array
strcpy(myArray[arrayIndexs+1], "string 3"); //

arrayIndexs = sizeof(*myArray)/sizeof(char*);

//Print out array values
printf("After: \n");
for (i = 0; i <= arrayIndexs; i++)
printf("Array[%d]: %s\n",i, myArray[i]);
}

Answer

If you ever find yourself attempting to use sizeof() for anything that is sized dynamically, you're doing it wrong. Keep that in mind. sizeof() is used repeatedly in this code incorrectly. Dynamic size counts must be managed by you; the allocation size requirements in bytes can be managed using those counts in conjunction with a sizeof() of the fundamental type for the item being stored.

Given that:

#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int i = 0;
    int arrayIndexes = 2;
    char ** myArray = malloc(arrayIndexes * sizeof(*myArray));

    //Allocate memory for each [x]
    for (i = 0; i < arrayIndexes; i++)
    {
        myArray[i] = malloc(254 * sizeof(char));
        sprintf(myArray[i], "string %d", i+1);
    }

    //Print out array values
    printf("Before: \n");
    for (i = 0; i < arrayIndexes; i++)
        printf("Array[%d]: %s\n", i, myArray[i]);

    // TODO: Fix this to check the result before orphaning the old
    //  value of myArray if an allocation failure ensues.
    myArray = realloc(myArray, (arrayIndexes+1) * sizeof(*myArray));
    ++arrayIndexes;

    //Allocate memory for the new string item in the array
    myArray[arrayIndexes-1] = malloc(254 * sizeof(char*));

    //Populate a new value in the array
    strcpy(myArray[arrayIndexes-1], "string 3"); //

    //Print out array values
    printf("After: \n");
    for (i = 0; i < arrayIndexes; i++)
        printf("Array[%d]: %s\n",i, myArray[i]);

    // TODO: write proper cleanup code just for good habits.
    return 0;
}

Output

Before: 
Array[0]: string 1
Array[1]: string 2
After: 
Array[0]: string 1
Array[1]: string 2
Array[2]: string 3