Код с вложенной структурой - как правильно распределить память? - PullRequest
0 голосов
/ 13 февраля 2019

Я написал этот код (*pdata)->pProd = (Product*)malloc(sizeof(Product)*size1);

Когда я ввел детали в "(*pdata)->pProd", компилятор остановился.Как я могу выделить память для "Product* pProd" и ввести данные?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    char name[30];
    int amount;
    int price;
}Product;

typedef struct
{
    int id;
    Product* pProd;
    int numProd;
}Cart;

void InitCashReg(Cart** pdata) {
    int size,size1,j=0,i;
    int PriceAllProd=0;

    printf("Enter number of client --> \n");
    scanf("%d", &size);

    printf("Enter number of product client bought --> \n");
    scanf("%d", &size1);

    *pdata = (Cart*)malloc(sizeof(Cart)*size);
    if (*pdata == NULL)
    {
        printf("cannot allocate memory\n");
        return -1;
    }
    (*pdata)->pProd = (Product*)malloc(sizeof(Product)*size1);
    if ((**pdata).pProd == NULL)
    {
        printf("cannot allocate memory\n");
        return -1;
    }

    …

1 Ответ

0 голосов
/ 14 февраля 2019

Один из комментариев говорит:

Мне нужно выделить место для size1 продуктов для каждого из size клиентов, а затем ввести сведения о продуктах для каждогоclient.

Перво-наперво:

  • Отделите размеры ввода-вывода от кода, который их использует.Это фундаментальный метод программирования.

Функция должна выполнять одну работу - ваша выполняет (как минимум) две: получить размеры и выделить место для данных, заданных этими размерами (и, вероятно, затемпродолжает заполнять пространство дополнительными операциями ввода / вывода).

Это означает, что ваш код должен быть разбит как минимум на две функции, вторая из которых становится чем-то вроде bool InitCashReg(size_t n_client, size_t n_prod, Cart **pdata), возвращая success / true илисбой / ложное состояние и принятие в качестве аргументов того, что вы называли size и size1, вместо того, чтобы пытаться их прочитать.Я не собираюсь копировать код ввода / вывода;Я просто сконцентрируюсь на коде выделения памяти.

enum { CLIENT_DEFAULT_ID = -1 };

bool InitCashReg(size_t n_client, size_t n_prod, Cart **pdata)
{
    Cart *cart = malloc(sizeof(*cart) * n_client);
    if (cart == 0)
        return false;
    for (size_t i = 0; i < n_client; i++)
    {
        cart[i]->pProd = calloc(sizeof(*cart[i]->pProd), n_prod);
        if (cart[i].pProd == 0)
        {
            // Release already allocated space
            for (size_t j = 0; j < i; j++)
                free(cart[j]->pProd);
            free(cart);
            return false;
        }
        cart[i].numProd = n_prod;
        cart[i].id = CLIENT_DEFAULT_ID;
    }
    *pdata = cart;
    return true;
}

Этот код не был скомпилирован, тем более проверен.

Iиспользовал calloc() для выделения массива продуктов, чтобы все данные обнулялись;вместо этого вы можете использовать malloc() и установить для переменных name, amount и price значение 0 другим способом.Обратите внимание, что это вместе с изобретенным CLIENT_DEFAULT_ID гарантирует, что вся выделенная память инициализируется известными значениями.

(C ++ имеет конструкторы, которые можно использовать для обеспечения правильной инициализации. C не имеет конструкторов, поэтомуВы должны убедиться, что выделенные данные правильно инициализированы.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...