malloc () và realloc () của cấu trúc
Chúng ta có thể cấp phát động bộ nhớ cho các cấu trúc không? Đây có phải là một thủ tục chính xác để tiếp cận một cấu trúc được cấp phát động không? Xin vui lòng cho tôi biết làm thế nào để malloc()và realloc()một cấu trúc.
newnode thuộc loại struct List * nhưng khi bắt đầu lập chỉ mục nó sẽ chuyển thành struct List. Làm thế nào để chuyển đổi này có thể? Hàm insert của tôi chỉ chấp nhận (struct List *) Tôi có nhầm chỗ nào không?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct List {
char val[20];
};
void insert(struct List *);
int main(void) {
int i = 0;
int size = 1;
struct List *newnode = (struct List *)malloc(size * sizeof(struct List));
for (i = 0; i < 5; i++) {
if (size <= i) {
size = size + size;
newnode = (struct List *)realloc(newnode, size * sizeof(struct List));
}
scanf("%s", newnode[i].val);
insert(newnode[i]);
}
for (i = 0; i < 5; i++) {
printf("%s\n", newnode[i].val);
}
return 0;
}
void insert(struct List *node) {
printf("%s\n", node->val);
}
Trả lời
Mã hoạt động ngoại trừ 3 vấn đề:
Bạn không kiểm tra lỗi cấp phát bộ nhớ. Cả hai
malloc()vàrealloc()sẽ trả vềNULLnếu không thể cấp phát bộ nhớ: bạn sẽ nhận được hành vi không xác định khi tham chiếunewnodenếu điều này xảy ra.để xử lý trường hợp
realloc()thất bại một cách khéo léo, bạn nên lưu trữ con trỏ được phân bổ lại vào một biến khác để bạn vẫn có thể truy cập vào mảng trước đó chưa được phân bổ và giải phóng nó.scanf("%s", newnode[i].val);là một lỗ hổng bảo mật: bạn nên giới hạn số byte có thể được lưu trữ cho mảng đích vớiscanf("%19s", newnode[i].val);bạn không kiểm tra giá trị trả về của
scanf()để phát hiện đầu vào không hợp lệ hoặc bị thiếu.insert()không chèn bất cứ thứ gì.
Đây là phiên bản đã sửa đổi với khả năng xử lý lỗi và tên ít gây nhầm lẫn hơn:
#include <stdio.h>
#include <stdlib.h>
struct Item {
char val[20];
};
//void insert(struct Item *);
int main(void) {
int i, j;
int size = 0;
struct Item *array = NULL;
for (i = 0; i < 5; i++) {
if (i >= size) {
int newsize = size ? 1 : size + size;
struct Item *newarray = realloc(array, sizeof(*array) * size);
if (newarray == NULL) {
perror("cannot reallocate the array");
break;
}
size = newsize;
array = newarray;
}
if (scanf("%19s", array[i].val) != 1) {
fprintf(stderr, "missing input\n");
break;
}
//insert(array[i]);
}
for (j = 0; j < i; i++) {
printf("%s\n", array[i].val);
}
free(array);
return 0;
}