malloc () и realloc () структур

Sep 30 2020

Можем ли мы динамически выделять память для структур? Это правильная процедура для подхода к динамически размещенным структурам? Подскажите пожалуйста как malloc()и realloc()структуру.

newnode имеет тип struct List *, но при запуске индексации он преобразуется в struct List. Как это преобразование возможно? Моя функция вставки принимает только (struct List *) Я где-то ошибаюсь?

#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);
}

Ответы

1 chqrlie Sep 30 2020 at 00:34

Код работает за исключением 3-х проблем:

  • Вы не проверяете сбой выделения памяти. Оба malloc()и realloc()вернутся, NULLесли память не может быть выделена: вы получите неопределенное поведение при разыменовании, newnodeесли это произойдет.

  • чтобы аккуратно обработать случай realloc()сбоя, вы должны сохранить перераспределенный указатель в другую переменную, чтобы вы по-прежнему могли получить доступ к предыдущему массиву, который не был освобожден, и освободить его.

  • scanf("%s", newnode[i].val); является недостатком безопасности: вы должны ограничить количество байтов, которые могут быть сохранены в целевом массиве, с помощью

    scanf("%19s", newnode[i].val);
    
  • вы не проверяете возвращаемое значение scanf()для обнаружения недопустимого или отсутствующего ввода.

  • insert()ничего не вставляет .

Вот модифицированная версия с обработкой ошибок и менее запутанными именами:

#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;
}