使用 'for' 并将指针作为循环变量时的无限循环
Infinite Loop when using 'for' with pointer as loop variable
我对编码很陌生,遇到了一个问题。我试图自己解决它并且一直在谷歌搜索很多,但我仍然没有解决方案。也许你们中的一个可以帮忙?
这是我的代码:
int main(int argc, char **argv) {
struct node {
char *str;
int count;
struct node *next;
};
struct node head = { argv[1], 1, NULL };
for (int i = 2; i < (argc); i++) {
for (struct node *p = &head; (p != NULL); p = p->next) {
printf("%s,%s\n", argv[i], p->str);
if (strcmp(argv[i], p->str) == 0) {
printf("case1\n");
p->count++;
break;
}
else if ((strcmp(argv[i], p->str) != 0) && p->next) {
printf("case2\n");
printf("Adresse, auf die p zeigt: %p", &p);
continue;
}
else if ((strcmp(argv[i], p->str) != 0) && (!p->next)) {
printf("case3\n");
struct node *oldhead = &head;
head.str = argv[i];
head.count = 1;
head.next = oldhead;
break;
}
}
}
// Print how many times each string appears
return 0;
}
目标是创建一个链表,其中包含我在调用程序时提供给 main()
的所有参数。如果有重复,结构应该计算它们。例如,如果我像 ./a.out foo fool foo
这样调用程序,结果应该是一个长度为 2 的列表,其中第一个元素包含字符串 "foo"
和计数 2
,第二个元素包含字符串 "fool"
,计数为 1
。问题是内部 for 循环中的 else if
语句。这是唯一应该实际使用内部 for 循环并将 p->next
分配给 p
的部分。不幸的是,这并没有发生。结果是内部 for 循环一遍又一遍地开始,指针 p 一直指向同一个地址(我用 printf 来计算)。
你们中有人知道这里可能出现的问题吗?我尽我所能并试图在网上找到解决方案...
非常感谢!!!
struct node *oldhead = &head;
head.str = argv[i];
head.count = 1;
head.next = oldhead;
这不是创建新节点。它只是创建对同一节点的新引用,因此当您尝试读取链表直到结束时会导致无限循环。因此,您的程序永远只有一个节点。您需要实际分配和创建新的。
这里的主要问题是
struct node *oldhead = &head;
你应该做的 malloc
:
struct node *oldhead = (struct node*) malloc(sizeof(struct node));
所以你真的为你的新节点分配了一块内存。因为你有 malloc
,你也应该在你的程序结束时做 free
:
while(...) {
free(deepest_node)
}
上面循环的方法是从链表中最远的节点一直回到head
。
另一个问题是,您不应该将新节点附加到 head
:
head.next = oldhead;
但应该指向 p
,这是您链表中的最后一个节点:
p -> next = oldhead;
问题出在这部分代码
else if ((strcmp(argv[i], p->str) != 0) && (!p->next)) {
printf("case3\n");
struct node *oldhead = &head;
head.str = argv[i];
head.count = 1;
head.next = oldhead;
break;
}
您需要分配一个新的结构,然后将其地址放在最后一个结构条目中。
else if ((strcmp(argv[i], p->str) != 0) && (!p->next)) {
printf("case3\n");
struct node *oldhead = p;
p = (struct node *) malloc(sizeof(node));
if (p == NULL) { .... manage the error ... }
oldhead->next = p;
p->str = argv[i];
p->count = 1;
p->next = NULL;
break;
}
现在您正在创建节点并将它们串在一起。您之前有效地更新了相同的 node
。
我对编码很陌生,遇到了一个问题。我试图自己解决它并且一直在谷歌搜索很多,但我仍然没有解决方案。也许你们中的一个可以帮忙?
这是我的代码:
int main(int argc, char **argv) {
struct node {
char *str;
int count;
struct node *next;
};
struct node head = { argv[1], 1, NULL };
for (int i = 2; i < (argc); i++) {
for (struct node *p = &head; (p != NULL); p = p->next) {
printf("%s,%s\n", argv[i], p->str);
if (strcmp(argv[i], p->str) == 0) {
printf("case1\n");
p->count++;
break;
}
else if ((strcmp(argv[i], p->str) != 0) && p->next) {
printf("case2\n");
printf("Adresse, auf die p zeigt: %p", &p);
continue;
}
else if ((strcmp(argv[i], p->str) != 0) && (!p->next)) {
printf("case3\n");
struct node *oldhead = &head;
head.str = argv[i];
head.count = 1;
head.next = oldhead;
break;
}
}
}
// Print how many times each string appears
return 0;
}
目标是创建一个链表,其中包含我在调用程序时提供给 main()
的所有参数。如果有重复,结构应该计算它们。例如,如果我像 ./a.out foo fool foo
这样调用程序,结果应该是一个长度为 2 的列表,其中第一个元素包含字符串 "foo"
和计数 2
,第二个元素包含字符串 "fool"
,计数为 1
。问题是内部 for 循环中的 else if
语句。这是唯一应该实际使用内部 for 循环并将 p->next
分配给 p
的部分。不幸的是,这并没有发生。结果是内部 for 循环一遍又一遍地开始,指针 p 一直指向同一个地址(我用 printf 来计算)。
你们中有人知道这里可能出现的问题吗?我尽我所能并试图在网上找到解决方案...
非常感谢!!!
struct node *oldhead = &head;
head.str = argv[i];
head.count = 1;
head.next = oldhead;
这不是创建新节点。它只是创建对同一节点的新引用,因此当您尝试读取链表直到结束时会导致无限循环。因此,您的程序永远只有一个节点。您需要实际分配和创建新的。
这里的主要问题是
struct node *oldhead = &head;
你应该做的 malloc
:
struct node *oldhead = (struct node*) malloc(sizeof(struct node));
所以你真的为你的新节点分配了一块内存。因为你有 malloc
,你也应该在你的程序结束时做 free
:
while(...) {
free(deepest_node)
}
上面循环的方法是从链表中最远的节点一直回到head
。
另一个问题是,您不应该将新节点附加到 head
:
head.next = oldhead;
但应该指向 p
,这是您链表中的最后一个节点:
p -> next = oldhead;
问题出在这部分代码
else if ((strcmp(argv[i], p->str) != 0) && (!p->next)) {
printf("case3\n");
struct node *oldhead = &head;
head.str = argv[i];
head.count = 1;
head.next = oldhead;
break;
}
您需要分配一个新的结构,然后将其地址放在最后一个结构条目中。
else if ((strcmp(argv[i], p->str) != 0) && (!p->next)) {
printf("case3\n");
struct node *oldhead = p;
p = (struct node *) malloc(sizeof(node));
if (p == NULL) { .... manage the error ... }
oldhead->next = p;
p->str = argv[i];
p->count = 1;
p->next = NULL;
break;
}
现在您正在创建节点并将它们串在一起。您之前有效地更新了相同的 node
。