0

I have an array of strings that is dynamically sized (I won't know the size of the strings at compile) that keeps giving me a segmentation fault error. The array is contained in a struct called hm and it has an array for the strings as well as an array for values. This part of the code is only to resize the string array properly when a new string is added to the struct. I am relatively new to C and structs, so if there is a better way to implement this I would love to hear about it. I have already tried looking around for this situation and most seem to be having the issue with the outer array using sizeof(char) instead of sizeof(char*), but when I changed that the issue still happens.

//problematic part of the function
char** t = (char**)realloc(hm->keys, hm->size * sizeof(char*));
if (t) hm->keys = t;
for (i = 0; i < hm->size; i++) {
    char* temp = (char*)realloc(hm->keys[i], hm->largestKey * sizeof(char)); //seg fault here
    if (temp) {
        hm->keys[i] = temp;
    }
}

//struct
typedef struct HM_struct {
    size_t size;
    size_t largestKey;
    char** keys;
    int* values;

    void (*add)(struct HM_struct* hm, char* key, int value);
} HM;
hudsons1033
  • 23
  • 1
  • 7
  • Your code does call either `malloc()` or `calloc()` before calling `realloc()`, right? – ryyker Oct 29 '20 at 01:42
  • You can't use `realloc()` there because not all of the `hm->keys[i]` have been initialized. – Barmar Oct 29 '20 at 01:42
  • 3
    [dont cast malloc](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Barmar Oct 29 '20 at 01:42
  • You can use `realloc()` for the elements that were in the `keys` array before you reallocated it, but you have to use `malloc()` for the new elements that were added. – Barmar Oct 29 '20 at 01:43
  • Which means you need to save the old size before you grow the array. – Barmar Oct 29 '20 at 01:44
  • @Barmar thank you, you were right, I forgot to do ```malloc()``` for the newly added string. As for casting, that's something my professor told me to do, so I will probably keep doing that as long as I am in the class. – hudsons1033 Oct 29 '20 at 02:16

1 Answers1

1

The problem is that when you realloc() and increase the allocated memory size, the new memory is not initialised (or with a debug library, initialised to a sentinal value). So, assuming you know the oldSize, a quick fix is:

char** t = realloc(hm->keys, hm->size * sizeof(char*)); // As before
if (t) hm->keys = t; // As before
for (i = oldSize; i < hm->size; i++)
    hm->keys[i] = NULL;

Now, according to the realloc() definition, when you call:

char* temp = realloc(NULL, hm->largestKey * sizeof(char));

It behaves as:

char* temp = malloc(hm->largestKey * sizeof(char));
Ken Y-N
  • 14,644
  • 21
  • 71
  • 114