0

I'm trying to solve a problem I'm having with a function that will create a new struct objects and then put it in an dynamic array. I have tried multiple variations but i keep running into various problems. This is what I'm working with right now, but I'm getting a memory access problem.

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

This code gives me: Exception thrown: read access violation. cardList was 0x64.

I've been reading alot about pointers and memmory allocation but obviously i am missing something..

7
  • Turn warnings of your compiler on and fix the warnings it gives. Commented Oct 25, 2018 at 15:33
  • 1
    "keyCreate(&cardList, 0);" ==> keyCreate(cardList, 0); Commented Oct 25, 2018 at 15:33
  • 1
    keyCreate expects a keycard* type, but you're passing in a keycard** type Commented Oct 25, 2018 at 15:33
  • First of all , keycard *cardList = NULL; Commented Oct 25, 2018 at 15:43
  • @TsakiroglouFotis and in the next line it is pointed to allocated memory. Commented Oct 25, 2018 at 15:46

2 Answers 2

1

You if you want to duynamically add new cards to the array, you need to wrap it in another data structure:

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;
}
Sign up to request clarification or add additional context in comments.

Comments

0

You are passing the incorrect type to keyCreate. This function expects a pointer to keycard, but you are passing it a double pointer instead. The & means "take the address of", which turns cardList into a keyCard** type. Instead, consider the following:

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

Also, time_t is most likely a signed integer (What is ultimately a time_t typedef to?), so assigning it to 0.0 is probably not right, but you'll need to check what it typedefs to on your system.

Finally, I assume this is just an MCVE, but I'd advise against mallocing in this case. The 2 primary reasons to malloc are when you don't know how much data you'll need until runtime, or you need "a lot" of data. Neither of those are true in this case. Just from what you've presented, I'd probably do the following:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.