未创建多个队列-C

未创建多个队列-C,c,arrays,struct,queue,message-queue,C,Arrays,Struct,Queue,Message Queue,起初,我创建这个程序是为了满足一个队列的需要,并且一切正常。目前,我正在尝试创建多个队列,方法是使用一个结构数组,每个队列都用自己的ID标识。但似乎它仍然只创建一个队列(就像我使用一个函数列出所有队列时,它只列出一个),我需要一些帮助来修复它。代码如下所示: #define MAX_MESSAGES 5 #define MAX_MSG_LEN 20 #define MAX_QUEUES 5 typedef struct queue{ int fr

起初,我创建这个程序是为了满足一个队列的需要,并且一切正常。目前,我正在尝试创建多个队列,方法是使用一个结构数组,每个队列都用自己的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;
}

虽然我最小化了程序以指出程序中的第一个问题,但是我有更多关于这些多队列的函数

这一行正在创建内存泄漏:

pq = createQ(qs[i].id);
createQ
正在返回一个指向
queue\t
实例的有效指针,并将其分配给
pq
。但是,在下一次迭代中,
pq
将被分配给
queue\t
的新实例
pq
只能指向
queue\t
的单个实例,因此无法再访问上一次迭代中的实例。这是一个典型的内存泄漏。有几种方法可以解决这个问题,但归根结底,它可以有多个指向
queue\u t
的指针。看起来您尝试了使用
MsgQs\u t
结构的正确方法。我将提供一个解决方案,该解决方案与您尝试的解决方案相匹配

首先,这一定义:

typedef struct MsgQs{
    int id;
    queue_t *qs[MAX_QUEUES];
}MsgQs_t;
创建
MsgQs\u t
的实例时,现在有一个固定大小的数组
MAX\u QUEUES
。createQ中的
malloc
重写了这个队列数组。在实例化
MsgQs\u 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;
您还需要更改
初始值emsgqs\u t
中的
malloc
大小:

//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\u队列
类型为
MsgQs\u t
的结构数组。然后,可以在循环中直接分配给它们。下面是循环的重新编写版本。我更改了while循环,因为我们不想循环传递的MAX_队列。访问
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;
    }
}
while(i
您确定只创建了1个吗?At
pq=createQ(qs[i].id)
,看起来您正在创建许多,但每次迭代都要用新的替换
pq
。@Jason我不是100%确定,我认为您是对的。如何修复它,使其不被每次迭代替换?