c - 如何正确重新分配内存?

标签 c pointers

对于我的程序,我正在尝试重新分配内存,以便可以将另一个人添加到数据库中。但是,当我输入新条目的名字后,我不断收到 EXC_BAD_ACCESS 错误。

void addRecord (char **firstName, char **lastName, double *scores, int *numberPeople) {
int i;
char **newFirstName, **newLastName;
double *newScores;

*numberPeople += 1; // adds person to total number of people

newFirstName = (char**) realloc(firstName,*numberPeople*sizeof(char*));
newLastName = (char**) realloc(lastName,*numberPeople*sizeof(char*));
newScores = (double*) realloc(scores,1*sizeof(double));

for (i = *numberPeople - 1; i < *numberPeople; i++) {
    newFirstName[i] = (char*) realloc(firstName, MAXIMUM_DATA_LENGTH*sizeof(char)); // MAXIMUM_DATA_LENGTH = 50
    newLastName[i] = (char*) realloc(lastName, MAXIMUM_DATA_LENGTH*sizeof(char));
}


printf("Adding New Person....\n\n");

for (i = *numberPeople - 1; i < *numberPeople; i++) {
    printf("First Name of new person: ");
    scanf("%s", newFirstName[i]); // EXC_BAD_ACCESS (code=EXC_l386_GPFLT)

    printf("Last Name of new person: ");
    scanf("%s", newLastName[i]);

    printf("Score of new person: ");
    scanf("%lf", &newScores[i]);
}

我只能假设我没有正确地重新分配内存。我对来自 Java 的 C 语言还比较陌生,所以我对指针的技能水平相当低。提前致谢。

最佳答案

一般而言,请在启用所有警告 ( -Wall ) 的情况下进行编译,并确保您不会收到任何警告。其次,简化你的方法(见下文)。第三,你需要valgrind检测您的指针(错误)使用错误。

这里似乎比必要的复杂得多。

例如在这一点中:

for (i = *numberPeople - 1; i < *numberPeople; i++) {
    newFirstName[i] = (char*) realloc(firstName, MAXIMUM_DATA_LENGTH*sizeof(char)); // MAXIMUM_DATA_LENGTH = 50
    newLastName[i] = (char*) realloc(lastName, MAXIMUM_DATA_LENGTH*sizeof(char));
}

在每次迭代中,您都会调用 realloc()firstName作为论点。这会释放firstName处的数据并分配不同大小的新数据集。在第一次通过时这很好(理论上),但在第二次通过时将释放已经释放的东西。与 lastName 相同。而且firstNamelastName不指向单个条目,它们指向数组本身,所以这是错误的。 IE 在处理数组的各个条目的循环的每次传递中,都会释放整个数组。

接下来为什么会这样for循环迭代i = *numberPeople - 1; i < *numberPeople ?这始终是一项。

另外检查来自 realloc() 的返回。如果(例如)您的阵列不正确,会发生什么 malloc() d 在调用 realloc() 之前第一次?

另一个问题是您将数组传递为 char **到这个函数。但随后您可以修改数组的位置。返回时,数组的新位置将丢失。

很难看出你想在这里做什么。我建议您使用更简单的方法:

  • 展开数组,
  • 将三个变量读入最终元素

不需要for循环。

这是一个简单的返工。我没有对此进行测试,因为您没有提供最小的完整可验证示例,但它应该对您有所帮助。

// note we use char*** as these are pointers to an array of char *
void
addRecord (char ***firstName, char ***lastName, double **scores,
           int *numberPeople)
{
  // the index we will use
  int i = *numberPeople;
  // add one to the number of people
  (*numberPeople)++;

  // expand the arrays - you should check for NULL returns here
  *firstName = realloc (*firstName, *numberPeople * sizeof (char *));
  *lastName = realloc (*lastName, *numberPeople * sizeof (char *));
  *scores = realloc (*scores, *numberPeople * sizeof (char *));

  // allocate memory for the new first and last name to live in
  *firstName[i] = malloc (MAXIMUM_DATA_LENGTH * sizeof (char));
  *lastName[i] = malloc (MAXIMUM_DATA_LENGTH * sizeof (char));

  printf ("Adding New Person....\n\n");

  printf ("First Name of new person: ");
  // your format string should be amended to limit the input length to MAXIMUM_DATA_LENGTH - 1
  // and you should check for errors
  scanf ("%s", newFirstName[i]);

  printf ("Last Name of new person: ");
  // your format string should be amended to limit the input length to MAXIMUM_DATA_LENGTH - 1
  // and you should check for errors
  scanf ("%s", newLastName[i]);

  printf ("Score of new person: ");
  // you should check for errors
  scanf ("%lf", &newScores[i]);
}

关于c - 如何正确重新分配内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36680065/

相关文章:

c - qsort段错误

c - 管道到标准输出

java - 用于通过网络发送对象、保留指针的模式/库

c - 简单赋值中的段错误

c - 指向 2D char 数组的指针和指向 2D int 数组的指针有什么区别?

c++ - 我怎样才能通过引用传递这个指针?

c - 编译后立即在cmd上运行程序(vscode上的Code Runner插件)

c - STM32VLDiscovery定时器中断HardFault c

字符数组转整数

C 在数组中存储变量的地址