Dynamic memory/realloc string array

24,786

Solution 1

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

Solution 2

You shall replace this line:

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

by something like this:

arrayIndexs += 1;

Reason: sizeof is a compile-time operator to determine the size of a datatype or datatype of an object, while here you shall manually maintain the array size.

EDTIED: Also when initializing the variable, you shall use

int arrayIndexs = 2;

instead of

int arrayIndexs = sizeof(*myArray) / sizeof(char*);
Share:
24,786
MrDB
Author by

MrDB

Updated on November 11, 2020

Comments

  • MrDB
    MrDB over 3 years

    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]);
    }
    
  • MrDB
    MrDB about 10 years
    Thanks for the good & quick answer - much appreciated, marked WhozCraig as the best answer due to full reworked code example.