【问题标题】:Why does my C program crash when I try to realloc() a pointer array of structs?当我尝试重新分配()结构指针数组时,为什么我的 C 程序会崩溃?
【发布时间】:2022-01-10 08:22:02
【问题描述】:

在下面的代码中,我尝试使用 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);
}

然而,每当我运行它时,它都会运行到输入提示符,然后在 realloc() 尝试时崩溃。我仍然无法弄清楚为什么或如何解决它。对 C 来说相当新,因此非常感谢您提供详细的解释,并且会有很长的路要走。

【问题讨论】:

  • InitArr 在 main() 中的堆栈上分配。你不能重新分配它。你必须 malloc 它,就像你对第一个 arr 做的那样(然后你扔掉而不释放)。
  • 另外,你改变了 inputKeyVal 的arr,但你永远不会改变main 的,所以在调用inputKeyVal 之后任何arr 的使用都是错误的。
  • keyValPair* arr = malloc(n * sizeof(keyValPair)); arr = initArr; 这是错误的,您正在创建内存泄漏。在arr = malloc(..) 之后,arr 指向一些内存(除非malloc 失败)。当您执行arr = initArr 时,您重新分配arr 以指向initArr。现在,没有任何内容指向您刚刚分配的内存,因此无法使用或freed。另外如前所述,现在arr 指向非reallocable 内存。
  • gekii_, char inputKey[25]; .... scanf(" %24s", &amp;inputKey); 表示您正在编译时未启用所有警告。节省时间,启用所有警告。

标签: c struct malloc realloc


【解决方案1】:

我认为存在三个问题。

arr = initArr;initArr覆盖arr的地址,使realloc不能取到malloc分配的地址。 为保留malloc分配的地址,需要将initArr的内容复制到arr中。

#include <stddef.h>

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

scanf 的最后一个参数是错误的。 &amp; 是不必要的。

scanf("%24s", inputKey);

inputKeyVal 之后,main 处的arr 丢失有效地址,因为它在inputKeyVal 中重新分配。 如果你需要realloc重新分配的正确地址,inputKeyVal应该返回重新分配的地址。

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

int main() {
  /* snipped */
  arr = inputKeyVal(arr, n);
  /* do something for arr */
  free(arr);
  return 0;
}

【讨论】:

    猜你喜欢
    • 2019-04-18
    • 2017-12-25
    • 2013-08-30
    • 1970-01-01
    • 1970-01-01
    • 2022-12-29
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多