C 创建结构对象并将其放入数组

C 创建结构对象并将其放入数组,c,memory-management,struct,C,Memory Management,Struct,我试图解决一个函数的问题,这个函数将创建一个新的struct对象,然后将它放入一个动态数组中。我尝试了多种变体,但我一直遇到各种问题。这就是我现在正在处理的问题,但是我遇到了一个内存访问问题 typedef struct { int keynr; int access; time_t lastused; } keycard; void keyCreate(keycard *cardList, int keyid) { cardList[keyid].key

我试图解决一个函数的问题,这个函数将创建一个新的struct对象,然后将它放入一个动态数组中。我尝试了多种变体,但我一直遇到各种问题。这就是我现在正在处理的问题,但是我遇到了一个内存访问问题

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);
这段代码告诉我:抛出异常:读取访问冲突。 卡片列表为0x64


我已经读了很多关于指针和内存分配的书,但显然我遗漏了一些东西。

您将不正确的类型传递给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;
}
#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;
}
此外,time_t很可能是一个有符号整数,因此将其指定为0.0可能是不正确的,但您需要检查它在系统上的类型定义

最后,我假设这只是一个MCVE,但我建议在这种情况下不要使用mallocing。使用malloc的两个主要原因是在运行时之前不知道需要多少数据,或者需要很多数据。在这种情况下,这两种说法都不正确。根据您所介绍的内容,我可能会做以下工作:

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

如果要向阵列动态添加新卡,需要将其包装到另一个数据结构中:

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

打开编译器的警告并修复它给出的警告。keyCreate&cardList,0;=>keyCreatecardList,0;keyCreate需要一个keycard*类型,但您要传入一个keycard**type首先,keycard*cardList=NULL@TsakiroglouFotis,在下一行中,它指向已分配的内存。