我对LinkedLists的经验很少,如果字符串在其中一个节点中,则无法确定测试的逻辑。整个程序正在等待客户端发送DNS查询,然后在无限循环中发回响应。我想做的是:
确定LinkedList是否具有客户端请求的主机名。如果不存在,则将其添加到LinkedList,并在执行查找后将答案保存到同一节点。如果它在那里,只需向客户端提供我已查找并存储在answer[]
中的答案。
以下是代码的简化部分:
struct queryCache {
char* hostName;
uint8_t answer[UDP_RECV_SIZE];
struct queryCache* next;
};
struct queryCache* qcRoot;
int main (int argc, char** argv) {
// ...unrelated code
qcRoot = malloc(sizeof(struct queryCache));
qcRoot->hostName = 0;
qcRoot->next = 0;
while (1) {
// Wait for client with recvfrom()
char* cqHostName;
// Code that malloc()s and strcpy()s the client hostname into cqHostName
// Determine if cqHostName is in the cache
int hostNameInCache = 0;
struct queryCache* currQC = qcRoot;
while (currQC) {
if (!strcmp(currQC->hostName, cqHostName)) {
puts("In the cache");
hostNameInCache = 1;
break;
}
currQC = currQC->next;
}
// If cqHostName is not in the cache add its name
if (!hostNameInCache) {
currQC->hostName = malloc(strlen(cqHostName)+1);
strcpy(currQC->hostName, cqHostName);
printf("Added HOSTNAME: %s to the cache\n", cqHostName);
currQC->next = malloc(sizeof(struct queryCache));
currQC = currQC->next;
currQC->hostName = 0;
currQC->next = 0;
}
// Code that does a recursive DNS
// Code that will copy the response into the appropriate answer[] of the LinkedList
}
}
该程序似乎只是在第一个客户端请求后退出而没有给出错误。如果我删除LinkedList代码它就可以正常工作,所以我很确定出错的地方与我如何检查字符串是否在LinkedList中有关。
答案 0 :(得分:1)
当hostNameInCache
为0时,很可能currQC
为NULL
,因此您无法推迟。
将while循环的条件更改为
#------------v
while (currQC->next) {
if (!strcmp(currQC->hostName, cqHostName)) {
puts("In the cache");
hostNameInCache = 1;
break;
}
currQC = currQC->next;
}
答案 1 :(得分:1)
根据您的代码,当您尝试执行currQC->hostName = malloc(strlen(cqHostName)+1);
时,currQC为空。
你接受的答案恰好是为了解决这个特定的情况,确实,在em循环中但是,如果你while(currQC->next)
那么你错过了检查最后一个列表中的项目。
因此,该代码引入了另一个问题,并不是立即显现出来的。我建议检查下一个元素是否为null,而不是像if (!currQC->next) break; else currQC=currQC->next
中的那样。
编辑:当然,我的建议意味着你想用do {}替换while循环while(1);相反,因为while条件将不再被测试。
答案 2 :(得分:0)
在C中,通常有两种方法来处理单链表:作为堆栈或队列。
将列表作为堆栈处理时,可以在头部添加新项目。将其作为队列处理时,您可以在尾部添加新项目。
最简单的是stack-method:
struct node
{
int data;
struct node *next;
};
...
struct node *head = NULL;
/* Add one node */
struct node *n1 = malloc(sizeof(struct node));
n1->data = 1;
n1->next = head; /* This and the next line is what adds the node */
head = n1;
/* Add another node */
struct node *n2 = malloc(sizeof(struct node));
n2->data = 2;
n2->next = head; /* This and the next line is what adds the node */
head = n2;
在上面的代码之后,该列表包含两个节点:
2 --> 1 --> NULL
对于队列方法,您需要跟踪尾部和头部:
struct node *head = NULL;
struct node *tail = NULL;
/* Add one node */
struct node *n1 = malloc(sizeof(struct node));
n1->data = 1;
n1->next = NULL;
if (tail != NULL)
tail->next = n1;
else
{
/* List is empty */
head = tail = n1;
}
/* Add another node */
struct node *n2 = malloc(sizeof(struct node));
n2->data = 2;
n2->next = NULL;
if (tail != NULL)
tail->next = n2;
else
{
/* List is empty */
head = tail = n2;
}
此后列表看起来像
1 --> 2 --> NULL
我建议您多次阅读此答案,并考虑一下您对列表的处理方式与此处使用的方法的不同之处。我还建议您使用调试器逐行查看代码,以查看列表处理无法按预期工作的原因。