未创建多个队列-C

问题描述 投票:0回答:1

起初,我正在创建此程序来满足一个队列,并且一切正常。我目前正在尝试通过使用结构数组创建多个队列,每个队列都使用自己的ID进行标识。但是似乎它仍然仅创建一个队列(因为当我使用列出所有队列的函数时,它仅列出一个队列),并且在修复它时我需要一些帮助。可以在下面找到代码:

    #define MAX_MESSAGES 5
    #define MAX_MSG_LEN 20
    #define MAX_QUEUES 5

    typedef struct queue{
        int front, rear, size;
        char elements[MAX_MESSAGES][MAX_MSG_LEN];
    }queue_t;

    typedef struct MsgQs{
        int id;
        queue_t *qs[MAX_QUEUES];
    }MsgQs_t;


int main(){
int id, i = 0;

    MsgQs_t *qs = initializeMsgQs_t();
    //MsgQs_t *qs = NULL;
    queue_t *pq = NULL;

while(1){
        printf("\n1) Create new queue");
        printf("\n0) Quit");
        printf("\nEnter choice:");
        scanf(" %c", &choice);
        getchar();

        switch(choice){
            case '1': //createQ
                printf("\nCreating a queue!\nEnter Queue-ID (Ex. 1234):");
                scanf("%d", &qs[i].id);
                pq = createQ(qs[i].id);
                printf("Queue with ID %d has been created successfully!\n", qs[i].id);
                i++;
                break;
            case '0':
                printf("\nQuitting");
                exit(1);
            default:
                printf("Incorrect. Re-enter.\n");
                break;
        }
    }
}

MsgQs_t* initializeMsgQs_t(){
    MsgQs_t* qs = malloc(sizeof(MsgQs_t));

    return qs;
}

queue_t* createQ(){

    queue_t* pq = malloc (sizeof(queue_t));

    pq -> front = 0;
    pq -> rear = 0;
    pq -> size = 0;

    return pq;
}

尽管我将程序最小化以指示我的程序中遇到的第一个问题,但我对这些多个队列还有更多的功能。

c arrays struct queue message-queue
1个回答
0
投票

此行正在造成内存泄漏:

pq = createQ(qs[i].id);

createQ返回指向queue_t实例的有效指针,并将其分配给pq。但是,在下一次迭代中,pq将分配给queue_t的新实例。 pq只能指向queue_t的单个实例,因此不再可以访问上一次迭代的实例。这是经典的内存泄漏。有几种方法可以解决此问题,但是归结为具有多个指向queue_t的指针。似乎您对MsgQs_t结构采取了正确的方法。我将提供一种适合您所要尝试的解决方案。

首先定义:

typedef struct MsgQs{
    int id;
    queue_t *qs[MAX_QUEUES];
}MsgQs_t;

[创建MsgQs_t的实例时,现在具有固定大小queue_t*的数组MAX_QUEUES。 createQ中的malloc正在覆盖此queue_t *数组。实例化MsgQs_t时,您已经为指针分配了空间。这只是对堆栈与堆分配的误解。这是带有char*的简单示例。

char* charptr = malloc(10);  /* heap allocation requires malloc */
char chararray[10];          /* This is ALREADY allocated 10 chars on the stack */

因此您可以直接将其直接分配给结构成员qs。很难说,但是看来您的意图是实际上每个队列有1个id。如果是这种情况,则您的结构定义应如下所示:

typedef struct MsgQs{
    int id;
    queue_t *msgQueue; /* changed name to avoid confusion */
}MsgQs_t;

您还想在malloc中更改initializeMsgQs_t的大小:

//This allocates MAX_QUEUES MsgQs_t structs
MsgQs_t* qs = malloc(MAX_QUEUES * sizeof(MsgQs_t));

//This only allocates 1:
MsgQs_t* qs = malloc(sizeof(MsgQs_t));

现在,您已经为堆分配了类型为MAX_QUEUESMsgQs_t结构的数组。然后,您可以直接在循环中分配给它们。下面是循环的重写版本。我更改了while循环,因为我们不想循环通过MAX_QUEUES。访问qs[MAX_QUEUES]将是未定义的行为,并且可能会导致分段错误。

while (i < MAX_QUEUES) {
    printf("\n1) Create new queue");
    printf("\n0) Quit");
    printf("\nEnter choice: ");
    scanf("%c", &choice);
    getchar();

    switch(choice) {
        case '1': //createQ
            printf("\nCreating a queue!\nEnter Queue-ID (Ex. 1234):");
            scanf("%d", &qs[i].id);
            getchar();
            qs[i].msgQueue = createQ();
            printf("Queue with ID %d has been created successfully!\n", qs[i].id);
            i++;
            break;
        case '0':
            printf("\nQuitting");
            exit(1);
        default:
            printf("Incorrect. Re-enter.\n");
            break;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.