0

I'm trying to implement a dynamic array of strings. However I encountered a slight problem. I don't allocate the memory properly, but I have no idea what am doing wrong.

My structure for the dynamic array looks like:

typedef struct Array {
    char **ids;
    int size;
} dynamicArray;

I initialize it with:

void initArray(dynamicArray *array) {
    array = malloc(sizeof(dynamicArray));
    array->ids = NULL;
    array->size = 0;
}

Deallocate by:

void freeArray(dynamicArray *array) {
    if (array->size != 0) {
        for (int i = 0; i < array->size; i++) {
            free(array->ids[i]);
        }
        array->size = 0;
        array->ids = NULL;
    }
}

But now the real problem for me is inserting:

void insertArray(dynamicArray *array, char *name) {
    if (array == NULL) {
        return;
    }
    int length = strlen(name) + 1;
    array = realloc(array, (??));
    strcpy(array->ids[array->size++], name);
}

The program fails on the reallocation with: Exception has occurred.. I'm really not sure, what am I doing wrong. I know I should be also allocating the array of string, but have no idea how to put it in there. Could you guys please send me any hints??

Andula
  • 47
  • 1
  • 7
  • 2
    `initArray()` is not returning the pointer to its caller. – Barmar Nov 30 '20 at 22:59
  • Show how you're calling `initArray()`. – Barmar Nov 30 '20 at 23:02
  • If `initArray()` is supposed to allocate the `dynamicArray` structure, see https://stackoverflow.com/questions/13431108/changing-address-contained-by-pointer-using-function. If you're calling it with the address of an existing struct, then it shouldn't call `malloc()`. – Barmar Nov 30 '20 at 23:03
  • I have `dynamicArray array;` followed by `initArray(&array);` – Andula Nov 30 '20 at 23:07
  • And that variable is declared `dynamicArray array;`? Then you don't need to call `malloc()`, the memory is already in the variable. – Barmar Nov 30 '20 at 23:09
  • You should be allocating and reallocating `array->ids` – Barmar Nov 30 '20 at 23:10
  • Please post a [mcve]. All the variable declarations matter. – Barmar Nov 30 '20 at 23:10
  • So I can erase the `malloc(sizeof(dynamicArray));`?? However, how should I insert an element properly?? The strings don't have fixed length. – Andula Nov 30 '20 at 23:11
  • Your `realloc` call is making the same error you made in your init function, assuming that `array` itself is the thing requiring dynamic memory to grow... When in fact, it is `array->ids` that should be passed to `realloc`. You also need to allocate memory for the strings themselves. I think perhaps you are jumping ahead too far in your learning with this task, when you should first be learning the basics of memory management in C. – paddy Nov 30 '20 at 23:15

1 Answers1

2

The pointer that you need to reallocate is array->ids, not array. When you insert into the array you increase its size. Then the new element points to a copy of the name string.

void insertArray(dynamicArray *array, char *name) {
    if (array == NULL) {
        return;
    }
    int length = strlen(name) + 1;
    char *copy = malloc(length);
    if (copy == NULL) { // malloc failed
        return;
    }
    strcpy(copy, name);
    char **new_ids = realloc(array->ids, (array->size+1) * sizeof(char *));
    if (new_ids == NULL) { // realloc failed
        return;
    }
    array->ids = new_ids;
    array->ids[array->size++] = copy;
}
Barmar
  • 741,623
  • 53
  • 500
  • 612