简体   繁体   中英

Infinite Loop when using 'for' with pointer as loop variable

I am quite new to coding and got stuck with a problem. I tried to solve it myself and have been googling a lot, but I still do not have a solution to this. Maybe one of you can help?

This is my code:

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;
}

The goal is to create a linked list that contains all the arguments I gave to the main() when calling the program. If there is a duplicate, the structure should count them. For example, if i call the program like ./a.out foo fool foo the result should be a list of length two, where the first element contains the string "foo" and count 2 , and the second element contains the string "fool" and has a count of 1 . The problem is the else if -statement within the inner for loop. This is the only part where the inner for loop should actually be used and assign p->next to p . Unfortunately that is not happening. The result is that the inner for loop starts over and over again and the pointer p points to the same address all the time (I used printf to figure that out).

Does any of you have an idea what could be the problem here? I tried everything I could and tried to find a solution online ...

Thanks a lot!!!

The issue is in this part of the code

   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;
    }

You need to allocate a new struct and then put its address in the last struct entry.

       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;
        }

Now you're creating nodes and stringing them together. You were effectively updating the same node before.

        struct node *oldhead = &head;
        head.str = argv[i];
        head.count = 1;
        head.next = oldhead;

That's not creating a new node. It's just creating a new reference to the same node, therefore causing an infinite loop when you try to read the linked list until the end. Therefore, your program only ever has one node. You need to actually allocate and create new ones.

The main problem here is

struct node *oldhead = &head;

which you should do malloc :

struct node *oldhead = (struct node*) malloc(sizeof(struct node));

so you really allocate a piece of memory for your new node. And because you have malloc , you should do free at the end of your program as well:

while(...) {
   free(deepest_node)
}

the way you do the loop above is to go from the farthest node in the linked list all the way back to the head .

The other issue is that, you should not append your new node to head :

head.next = oldhead;

but should be to p , which is the last node in your linked list:

p -> next = oldhead;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM