0

In the code below, I'm trying to expand an array of key value structs using realloc().

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

typedef struct {
    char key[25];
    char value[25];
} keyValPair;

void inputKeyVal(keyValPair* arr, int n) {
    char inputKey[25];
    char inputVal[25];
    printf("input key: ");
    scanf(" %24s", &inputKey);
    printf("input value: ");
    scanf(" %24s", &inputVal);
    n++;
    arr = (keyValPair*) realloc( (keyValPair*) arr, n*sizeof(keyValPair));
    strcpy(arr[n-1].key, inputKey);
    strcpy(arr[n-1].value, inputVal);
}

int main() {
    keyValPair initArr[] = {{"foo", "bar"}, {"a", "b"}};
    int n = sizeof(initArr)/sizeof(keyValPair);
    keyValPair* arr = malloc(n * sizeof(keyValPair));
    arr = initArr;
    inputKeyVal(arr, n);
}

Whenever I run it however, it runs up to the input prompt, before crashing at the realloc() attempt. I still can't figure out why or how to fix it. Fairly new to C, so a detailed explanation would be much appreciated and would go a long way.

4
  • 3
    InitArr is allocated on the stack in main(). You can’t realloc that. You have to malloc it, as you do with the first arr (that you then throw away without freeing). Commented Dec 4, 2021 at 5:26
  • Also, you change inputKeyVal's arr, but you never change main's, so any use of arr after the call to inputKeyVal will be wrong. Commented Dec 4, 2021 at 5:36
  • 1
    keyValPair* arr = malloc(n * sizeof(keyValPair)); arr = initArr; This is wrong, you're creating a memory leak. After arr = malloc(..), arr points to some memory (unless malloc fails). When you do arr = initArr, you reassign arr to point to initArr. Now, nothing points to the memory you just allocated, so it can't be used or freed. Additionally as mentioned, now arr points to non-reallocable memory. Commented Dec 4, 2021 at 5:41
  • 1
    gekii_, char inputKey[25]; .... scanf(" %24s", &inputKey); implies your are compiling without all warnings enabled. Save time, enable all warnings. Commented Dec 4, 2021 at 5:57

1 Answer 1

2

I think that there are three problems.

arr = initArr; overwrites the address of arr by initArr, so that realloc can't take the address which has been allocated by malloc. To keep the address allocated by malloc, the contents of initArr should be copied into arr.

#include <stddef.h>

for (size_t i = 0; i < sizeof(initArr) / sizeof(initArr[0]); i++) {
   arr[i] = initArr[i];
}

The last argument for scanf is wrong. & is unnecessary.

scanf("%24s", inputKey);

After inputKeyVal, arr at main loses valid address because it is reallocated in inputKeyVal. If you require the correct address which has been reallocated by realloc, inputKeyVal should return the reallocated address.

keyValPair* inputKeyVal(keyValPair* arr, int n) {
  /* snipped */
  return arr;
}

int main() {
  /* snipped */
  arr = inputKeyVal(arr, n);
  /* do something for arr */
  free(arr);
  return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.