如何正确重新分配内存?

时间:2016-04-17 17:52:34

标签: 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相对较新的,所以我的指针技能水平非常低。提前谢谢。

1 个答案:

答案 0 :(得分:0)

总的来说,编译时启用所有警告(-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()之前没有正确realloc() d,会发生什么?

另一个问题是您将数组作为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]);
}