[英]How can I increase the array size with malloc?
我試圖制作一個 function 在結構數組中添加一個成員,然后增加其維度。
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 %s\n", 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
等。您可以節省一些麻煩並創建一些臨時變量以在 function 中使用。 在整個 function 中使用它們,然后將它們分配回 function 的末尾。
例子:
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;
}
另一種選擇是將值包裝在結構中並將指向該結構的指針傳遞給 function:
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
失敗了,原來的memory就丟失了。 使用臨時變量。
id *temp_list = realloc(list, size * sizeof(id));
if (temp_list) {
list = temp_list;
// Continue
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.