c-如何使用malloc增加数组大小



我试图制作一个函数,在结构的数组中添加一个成员,然后增加其维度。

void addMember(id **list, size_t *size)
{
(*size)++;
*list = *size == 1 ? malloc(sizeof(id)) : realloc(*list, *size * sizeof(id));
if(!list) {
printf("Dynamic allocation failed.n");
exit(1);
}

list[*size-1]->name = malloc (30 * sizeof(char));
list[*size-1]->surname = malloc (30 * sizeof(char));
list[*size-1]->number = malloc (15 * sizeof(char));
if(!list[*size-1]->name || !list[*size-1]->surname || !list[*size-1]->number) {
printf("Dynamic allocation failed.n");
exit(1);
}
printf("Name: ");
fgets(list[*size-1]->name, 30, stdin);
list[*size-1]->name[strcspn(list[*size-1]->name, "n")] = 0;
list[*size-1]->name = realloc (list[*size-1]->name, strlen(list[*size-1]->name) + 1 * sizeof(char));
if(strcmp(list[*size-1]->name, "") == 0) {
printf("You did not enter the name. Try again.n");
free(list[*size-1]->name);
(*size)--;
*list = realloc(*list, *size * sizeof(id));
return;
}
printf("Surname: ");
fgets(list[*size-1]->surname, 30, stdin);
surname[*size-1]->surname[strcspn(list[*size-1]->surname, "n")] = 0;
surname[*size-1]->surname = realloc (list[*size-1]->surname, strlen(list[*size-1]->surname) + 1 * sizeof(char));
if(strcmp(list[*size-1]->surname, "") == 0) {
printf("You did not enter the surname. Try again.n");
free(list[*size-1]->surname);
(*size)--;
*list = realloc(*list, *size * sizeof(id));
return;
}
printf("Number: ");
fgets(list[*size-1]->number, 15, stdin);
list[*size-1]->number[strcspn(list[*size-1]->number, "n")] = 0;
list[*size-1]->number = realloc (list[*size-1]->number, strlen(list[*size-1]->number) + 1 * sizeof(char));
if(strcmp(list[*size-1]->number, "") == 0) {
printf("You did not enter the number. Try again.n");
free(list[*size-1]->number);
(*size)--;
*list = realloc(*list, *size * sizeof(id));
return;
}
}

然而,当我尝试将第二个成员添加到数组时,遇到了一个问题。事实上,在第二次调用期间,程序在此处返回EXC_BAD_ACCESS错误:list[*size-1]->name = malloc (30 * sizeof(char));。相反,我可以毫无问题地进入第一个数组成员。我该如何解决?结构体为:

typedef struct {
char *name;
char *surname;
char *number;
} id;

编辑:

这是主文件:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "functions.h"
int main()
{
id *list = NULL;
size_t i, size = 0;
int choice;
srand((unsigned)time(NULL));

do {
printf("Enter '1' to display all members, enter '2' to add a new member, enter '3' to exit: ");
scanf("%d%*c", &choice);
putchar('n');

switch(choice) {
case 1:
if(size == 0)
printf("There's no members.n");
else
for(i = 0; i < size; i++)
printf("%s %sn", list[i].name, list[i].surname);
break;

case 2:
if(size < 30)
addMember(&list, &size);
break;
}

printf("Press start.");
getchar(); putchar('n');

} while(choice != 3);

free(list);

return 0;
}

list是指向id数组的指针,因此它应该是:(*list)[*size-1].name等。您可以省去一些麻烦,并创建一些临时变量来在函数中使用。在整个函数中使用这些,然后在函数结束时重新分配。

示例:

void addMember(id **list_original, size_t *size_original)
{
id *list = *list_original;
int size = *size_original;

size++;
list = size == 1 ? malloc(sizeof(id)) : realloc(list, size * sizeof(id));
if (!list) return; // Nothing to do as original values are untouched
list[size-1].name = malloc (30 * sizeof(char));
// etc...
*list_original = list;
*size_original = size;
}

另一种选择是将值包装在结构中,并将指向该结构的指针传递给函数:

typedef struct {
id *list;
size_t size;
} list_data;
void addMember(list_data *list)
{
// If you pass NULL to realloc it acts like malloc
id *tmp = realloc(list->list, (list->size + 1) * sizeof(id));
if (!tmp) return;
list->list = tmp;
list->list[list->size].name = malloc(30);
// etc...
list->size += 1;
}
int main()
{
list_data list = {NULL, 0};
addMember(&list);
// ....
}

旁注:在结果中使用传递给realloc的指针是不好的做法:

list = realloc(list, size * sizeof(id));

原因是如果realloc出现故障,则会丢失原始内存。使用温度变量

id *temp_list = realloc(list, size * sizeof(id));
if (temp_list) {
list = temp_list;
// Continue
}

最新更新