Создание объектов структуры и размещение их в массиве - PullRequest
0 голосов
/ 25 октября 2018

Я пытаюсь решить проблему с функцией, которая будет создавать новые объекты структуры и затем помещать ее в динамический массив.Я пробовал несколько вариантов, но я продолжаю сталкиваться с различными проблемами.Это то, с чем я сейчас работаю, но у меня проблема с доступом к памяти.

typedef struct  {
    int keynr;
    int access;
    time_t lastused;


} keycard;

void keyCreate(keycard *cardList, int keyid) {
    cardList[keyid].keynr = keyid + 100;
    cardList[keyid].access = 1;
    cardList[keyid].lastused = 0.0;
    }

int main () {
    keycard *cardList = 0;
    cardList = malloc(sizeof(keycard) * 1);
    keyCreate(&cardList, 0);
    printf("%d", cardList[0].access);

Этот код дает мне: Возникло исключение: нарушение прав чтения.cardList был 0x64.

Я много читал о указателях и распределении памяти, но, очевидно, я что-то упустил ..

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Если вы хотите динамически добавлять новые карты в массив, вам нужно обернуть его в другую структуру данных:

typedef struct  
{
    int keynr;
    int access;
    time_t lastused;
} keycard;

typedef struct 
{
    keycard *keyarray;
    size_t size;
}keystorage;

int keyCreate(keystorage *cardList, size_t keyid) 
{
    if (cardList -> keyarray == NULL || keyid + 1 > cardList -> size)
    {
        keycard *new = realloc(cardList -> keyarray, sizeof(*(cardList -> keyarray)) * (keyid + 1));

        if(!new) return -1;   //error
        cardList -> keyarray = new;
        cardList -> size = keyid + 1;
    }

    cardList -> keyarray[keyid].keynr = keyid + 100;
    cardList -> keyarray[keyid].access = 1;
    cardList -> keyarray[keyid].lastused = 0.0;
    return 0; //OK
}




int main (void) {
    keycard key;
    keystorage cards = {NULL, 0};

    keyCreate(&cards, 500);
    printf("%d", cards.keyarray[500].access);

    return 0;
}
0 голосов
/ 25 октября 2018

Вы передаете неправильный тип на keyCreate.Эта функция ожидает указатель на keycard, но вместо этого вы передаете ему двойной указатель.& означает «получить адрес», что превращает cardList в тип keyCard**.Вместо этого рассмотрим следующее:

void keyCreate(keycard *cardList, int keyid) {
    cardList[keyid].keynr = keyid + 100;
    cardList[keyid].access = 1;
    cardList[keyid].lastused = 0;  // time_t is most likely a signed integer
}

int main (void) {
    keycard *cardList = malloc(sizeof(keycard) * 1);
    // always check if malloc succeeds, and if it does not, handle the error somehow
    if (cardList == NULL)
    {
      fprintf(stderr, "Insufficient mem\n");
      return -1;
    }

    keyCreate(cardList, 0);
    printf("%d\n", cardList[0].access);  // the \n will flush the output and
                                         // put each item on its own line

    // cleanup when you're done, but the OS will do this for you when the
    // process exits also
    free(keyCreate);

    return 0;
}

Кроме того, time_t - это, скорее всего, целое число со знаком ( Что в конечном итоге означает type_t typedef для? ), поэтому присвоение его 0.0, вероятно,не правильно, но вам нужно проверить, к чему это typedef s в вашей системе.

Наконец, я предполагаю, что это просто MCVE, но я бы посоветовал не использовать malloc в этом случае.,Две основные причины malloc - это когда вы не знаете, сколько данных вам понадобится до времени выполнения, или вам нужно «много» данных.Ни один из них не является правдой в этом случае.Только из того, что вы представили, я бы, вероятно, сделал следующее:

#define NUM_KEY_CARDS 1

void keyCreate(keycard *cardList, int keyid) {
        cardList[keyid].keynr = keyid + 100;
        cardList[keyid].access = 1;
        cardList[keyid].lastused = 0;  // time_t is most likely a signed integer
    }

int main (void) {
    keycard cardList[NUM_KEY_CARDS];

    for (int keyid=0; keyid<NUM_KEY_CARDS; keyid++)
    {
        keyCreate(cardList+keyid, keyid);
        // or keyCreate(&(cardList[keyid]), keyid);
        printf("%d\n", cardList[keyid].access);
    }

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