未创建多个队列 - C
Multiple queues not being created - C
起初我创建这个程序是为了满足一个队列的需要,一切正常。我目前正在尝试创建多个队列,方法是使用一个结构数组,每个队列都用自己的 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_t
的指针。看起来您尝试了使用 MsgQs_t
结构的正确方法。我将提供一个适合您尝试做的事情的解决方案。
首先这个定义:
typedef struct MsgQs{
int id;
queue_t *qs[MAX_QUEUES];
}MsgQs_t;
当您创建 MsgQs_t
的实例时,您现在拥有一个固定大小 MAX_QUEUES
的数组 queue_t*
。 createQ 中的 malloc
覆盖了这个 queue_t* 的数组。当您实例化 MsgQs_t
时,您已经为您的指针分配了 space。这只是对堆栈与堆分配的误解。这是一个更简单的例子 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;
您还想更改 initializeMsgQs_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_QUEUES
类型 MsgQs_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;
}
}
起初我创建这个程序是为了满足一个队列的需要,一切正常。我目前正在尝试创建多个队列,方法是使用一个结构数组,每个队列都用自己的 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_t
的指针。看起来您尝试了使用 MsgQs_t
结构的正确方法。我将提供一个适合您尝试做的事情的解决方案。
首先这个定义:
typedef struct MsgQs{
int id;
queue_t *qs[MAX_QUEUES];
}MsgQs_t;
当您创建 MsgQs_t
的实例时,您现在拥有一个固定大小 MAX_QUEUES
的数组 queue_t*
。 createQ 中的 malloc
覆盖了这个 queue_t* 的数组。当您实例化 MsgQs_t
时,您已经为您的指针分配了 space。这只是对堆栈与堆分配的误解。这是一个更简单的例子 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;
您还想更改 initializeMsgQs_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_QUEUES
类型 MsgQs_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;
}
}