smritz
smritz

Reputation: 118

C - Doubly Linked List - Node's content is not correct (hard to explain)

I found this quite hard to explain in the title without actually showing the code and the problem...so here it goes. I am leaving out the methods that are working so it isn't as much to read.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <ctype.h>

struct tnode {
    struct tnode *prev;
    char *word;
    struct tnode *next;
};

struct tnode *talloc(void)
{
    ...
}

struct tnode *addlist(struct tnode *p, char *w)
{
    ...
}

void removelist(struct tnode *p, char *w)
{
    while (1)
    {
        if (strcmp(p->word,w) == 0)
        {
            p->next->prev = p->prev;
            p->prev->next = p->next;
            goto out;
        }
        else if (strcmp(p->word,w) > 0)
        {
            p = p->prev;
        }
        else p = p->next;
    }
out:;
    return p;
}

void tprint(struct tnode *root)
{
    ...
}

main()
{
    struct tnode *root;
    root = talloc();
    root->word = "doberman";
    root->next = talloc();
    root->prev = talloc();
    //I am using a blank string at the beginning and end instead of leaving it NULL. When I tried leaving it NULL, I would get inaccessability errors.
    root->next->word = "";
    root->prev->word = "";
    //I don't remember why I made "current" but it is working so I don't want to mess with it.
    struct tnode *current;
    current = talloc();
    current = root;
    current = addlist(root, "giraffe");
    current = addlist(root, "gemini");
    current = addlist(root, "apple");
    current = addlist(root, "azure");
    current = addlist(root, "rabbit");
    current = addlist(root, "zambia");
    current = addlist(root, "viking");
    current = addlist(root, "cat");
    current = addlist(root, "dog");
    current = addlist(root, "tree");
    current = addlist(root, "domino");
    removelist(root, "azure");
    tprint(root);
}

The removelist method currently removing more than it should, anywhere from 2-4 items instead of 1. When I step through the method in the bebugger, I notice that "p->word" does not match up with "p".

For example, the debugger will say that "p->word" is currently "doberman", and then tell me that "p" currently contains "apple".

My question is: How is this even possible? If "p" is the apple node, then how could "p->word" be doberman? It is really messing up the method, because it will think it is in the right spot to do the removal, when in fact it is not.

Upvotes: 0

Views: 69

Answers (4)

smritz
smritz

Reputation: 118

It ended up being a problem with the last thing I suspected...the print method. It seems like every question I ask here ends up like this...the answer has nothing to do with what I'm asking here, but all the answers still lead me to the solutions.

Anyway, thanks for the help.

Upvotes: 0

I think you still have to set p->next and p->prev to NULL. Otherwise, p can still be traversed. Maybe that is giving you the funny results.

Upvotes: 0

BoldAsLove
BoldAsLove

Reputation: 689

when comparing to see if you should delete your using

if (strcmp(p->word,w) > 0)

Which will return true when the first character that does not match has a greater value in ptr1 than in ptr2

I assume your wanting to remove the matching item, so thats a problem, but not the problem. Did you try printing out the list before you call remove to make sure all the items are added? And when you step through what happens when you hit the goto statement?

Upvotes: 1

GroovyDotCom
GroovyDotCom

Reputation: 1374

your first

if (strcmp(p->word,w) > 0)

should be

if (strcmp(p->word,w) == 0)

Upvotes: 1

Related Questions