这个程序实现了一个简单的链表队列(Queue),用来存储字符串数据。以下是对代码的详细分析:
结构体定义
DataNode:用于表示队列中的节点,每个节点包含指向数据的指针和下一个节点的指针。
typedef struct DataNode { char *data; // 存储字符串数据 struct DataNode *next; // 指向下一个节点 } DataNode;
Que:表示整个队列,包含头节点和尾节点的指针。
typedef struct { DataNode *head, *tail; } Que;
函数定义
queue_init:初始化队列,将头和尾指针设置为NULL。
void queue_init(Que *myroot) { myroot->head = NULL; myroot->tail = NULL; }
queue_put:将新创建的数据节点添加到队列末尾。如果队列不为空,则更新当前尾部节点的
next
指针;如果是空队列,初始化头部指针。void queue_put(Que *myroot, DataNode *myDataNode) { if (myroot->tail != NULL) myroot->tail->next = myDataNode; myroot->tail = myDataNode; if (myroot->head == NULL) myroot->head = myDataNode; }
queue_get:从队列中获取并移除头部的数据节点。如果获取成功,更新头部指针,并在需要时更新尾部指针。
DataNode *queue_get(Que *myroot) { DataNode *myDataNode = myroot->head; if (myroot->head != NULL) { myroot->head = myroot->head->next; myDataNode->next = NULL; // 将取出的节点的 next 置为 NULL if (myroot->head == NULL) // 如果新的头部为空,则更新尾部为 NULL myroot->tail = NULL; } else { myDataNode = NULL; // 如果没有元素可取,则返回NULL(修正此处错误) } return myDataNode; }
主函数逻辑
- 创建
Que
和DataNode
的实例,并初始化队列。 - 通过循环输入4个字符串,并将其放入队列中:
- 每次输入一个字符串,创建对应的
DataNode
并调用queue_put
加入到队列中。
- 每次输入一个字符串,创建对应的
- 使用循环从队列中获取并打印每个字符串,然后释放相应内存。
int main() {
Que *myroot;
DataNode *tmpNode;
char str[1024];
int ts, qs, i;
qs = sizeof(Que);
ts = sizeof(DataNode);
printf("sizeof(Que):%d,sizeof(DataNode):%d\n", qs, ts);
// 分配空间并初始化 Queue
myroot = (Que *)malloc(qs);
queue_init(myroot);
for(i=0; i<4; i++) {
scanf("%s", str); // 输入字符串
tmpNode=(DataNode *)malloc(ts); // 分配内存给新结点
tmpNode->data=(char *)malloc(strlen(str)+1); // 分配内存给数据字段
strcpy(tmpNode->data, str); // 复制输入字符串到新结点的数据字段
tmpNode->next=NULL;
queue_put(myroot, tmpNode); // 将新结点放入队列
printf("queue_put a node , used: %d\n", strlen(str)+1+ts);
}
while(myroot->tail != NULL) {
tmpNode=queue_get(myroot); // 从队列获取结点
if (tmpNode != NULL) { // 检查是否成功取得数据节点(修正此处潜在错误)
printf("queue_get a node: %s, freed:%d\n", tmpNode->data, strlen(tmpNode->data)+1+ts);
free(tmpNode->data); // 释放数据字段内存
free(tmpNode); // 释放结点内存
}
}
free(myroot); // 释放 Queue 内存
return 0; // 返回成功状态码
}
注意事项
在
queue_get
中,如果没有元素可供返回,应返回NULL
而不是重复引用未分配的指针。此外,在主函数里需要添加对返回值是否为NULL
的检查,以避免对空指针解引用。请确保使用适当的内存管理策略以防止内存泄漏。在这个例子中,每次使用
malloc
分配后都要相应地使用free
来释放分配出来的内存。
内容由零声教学AI助手提供,问题来源于学员提问