Problem with a linked list

I've written a small program to experiment with a linked list, but the add function doesn't work as supposed to. After adding an element with add(element, list) and asigning it to list - the list points with p_next value to itself. Can someone explain this strange behaviour?

kind regards
Hidden

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 #include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;

/*Write a program to remove an element from a linked list; 
the remove function should take just the element to be removed. 
Is this function easy to write—and will it be fast? Could this 
be made easier or faster by adding an additional pointer to the list?*/

struct namen{
	string name;
	namen *p_next;
};

namen add_name(namen *neuer_name, namen *liste){
	neuer_name->p_next = liste;
	cout<< neuer_name->name << " " << neuer_name->p_next->name <<endl;
	return *neuer_name;
}
int main(){
	namen erik;
	erik.name = "erik";
	erik.p_next = NULL;
	namen lina;
	lina.name = "lina";
	namen mili;
	mili.name = "mili";
	namen liste;
	liste = add_name(&lina, &erik); // cout lina erik 
	liste = add_name(&mili, &liste); // cout lina mili
	cout<< liste.name << " "  <<liste.p_next->name<< endl; // cout mili mili - why?
	cin.get();
}	
Last edited on
http://ideone.com/AJlJoU
I'm having a hard time understanding the program, you're doing weird things with your variables that don't make sense. Can you remove all unrelated code?
Thank you for replying so fast - now i've removed every irrelevant part of the code - I know i could use a pointer for the list - but i just want to unterstand why with true variables and not pointers it's not working.
What are liste and liste2 for? Why do you assign to them the return value of the function, by copy? Why do you use liste as an argument on line 32?
First i only had liste and not liste2(forget to delete liste2) - liste should be a list holding all possible items - so i can go through them with something like p_list = *liste and a while loop: while(p_list != Null). i know copying the return values isn't smart - but i just don't get why it result in an error - the add function should take the current list add the new element at the front and return the updated list - which after the operation should be the new list that's why i asign the return value to liste again.
Last edited on
Every namen variable is a node in a list. Your list elements, aka nodes, are erik, lina, and mili, but then you introduce liste which doesn't make sense.
Hm but liste is just a name for my linked list - i don't see a problem with this particular point - suppose i want to make more lists maybe one list with spanish speaking people and another one with english speaking people - i would then add some people to the "spanish_liste" and other people to the "english_liste" - i suppose you know the vector class - which is nothing more than a double linked_list - i would not like to have to name my list by the last node added - i want a separate name for it ... with vector it would be like vector<name> name_list(erik, lina) and i would not be pleased if i would have to name this list - erik cause it happens to be the first node. (That there is a name for every node and i don't simply add all the elements directly to the list - is cause i want to have a direct pointer access to every element i insert into the list). The big question i've is not concerned with how usefull and professsional this code is, but why does it not work - why does it print mili mili where it is supposed to print mili lina?
Last edited on
liste is not your list, it is a node in your list.
liste is the first node in my list or ? and i should be able to access all information in the list via the first node or not? - (yes liste is the name of the first node inside the list - that is how i defined it - but only the first node inside the list needs a name - cause all the other information is inside the structure via pointers - there is no need for a special name for every node - and naming the first node name_list makes totally sense to me. In no other way the vector class is defined just via a class and not a struct - but it's named after the first node)
Last edited on
closed account (z05DSL3A)
Take a look at:
http://www.cplusplus.com/forum/lounge/130932/#msg706446

you might see the distinction between List and Node (ListElement) that LB is alluding too.
Thank you Canis lupus,
yes it's true in your implementation and i suppose in the implementation of a vector and stuff like this is indeed a distinction between a List and Node - sorry for doupting this LB. But still i've no clue why the program is given me the output Mili Mili and not Mili Lina why is after this line: liste = add_name(&mili, &liste); liste not a node containing all information of the names added to it, but a node with a p_next pointer pointing to itstelf?

PS: If you know please explain a little bit in detail - if you write the implementation makes no sense i'm not able to understand this specific behaviour of the program.
Last edited on
closed account (z05DSL3A)
It is a bit tricky to explain (without diagrams) but I'll give it a go.

For the sake of simplicity I'm going to use simple numbers as addresses.

Lets say that mili is at address 95 and liste is at address 100.

You pass those numbers into the add_name(), in there you set milis next pointer to point to address 100. When you return from add_name() you copy mili to address 100.

When you then look at liste, it is a copy of mili so has the name 'mili' and its next pointer points to address 100...

hopefully that makes sense.

------------------------------------------------------------------------------------
Some minor changes to your code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
struct namen
{
	string name;
	namen *p_next;
};


namen * add_name(namen *neuer_name, namen *liste)
{
	neuer_name->p_next = liste;
	return neuer_name;
}

int main()
{
	namen erik;
	erik.name = "erik";
	erik.p_next = NULL;

	namen lina;
	lina.name = "lina";
	lina.p_next = NULL;
	
	namen mili;
	mili.name = "mili";
	mili.p_next = NULL;
	
	namen * liste = NULL;
	
	liste = add_name(&erik, liste);
	liste = add_name(&lina, liste);
	liste = add_name(&mili, liste); 

	namen * current = liste;
	while (current != NULL)
	{
		cout << current->name << endl;
		current = current->p_next;
	}
	
	cin.get();
}
mili
lina
erik
Last edited on by Canis lupus
closed account (D80DSL3A)
Ok. Let's look at it line by line.
1
2
3
4
5
6
7
8
9
10
11
namen erik;
erik.name = "erik";
erik.p_next = NULL;
namen lina;
lina.name = "lina";
namen mili;
mili.name = "mili";
namen liste;
liste = add_name(&lina, &erik); // cout lina erik 
liste = add_name(&mili, &liste); // cout lina mili <-NO, output is: mili lina
cout<< liste.name << " "  <<liste.p_next->name<< endl; // cout mili mili - why? 


This line: liste = add_name(&lina, &erik); // cout lina erik
leaves liste.name = "lina", liste.p_next = &erik;

Similarly, this line:
liste = add_name(&mili, &liste);// cout mili lina
leaves liste.name = "mili", liste.p_next = &liste;
ie. liste is left with its p_next pointing to itself.
So yes, cout<< liste.name << " " <<liste.p_next->name<< endl; gives mili mili.

You can make it work though.
Replacing lines 31-33 with this:
1
2
3
4
add_name(&lina, &erik); // cout lina erik
liste = add_name(&mili, &lina); // cout mili lina
for( namen* it = &liste; it != NULL; it = it->p_next ) cout << it->name << " ";
	cout << endl;// cout mili lina erik 

The 1st line links lina to erik
The 2nd line links mili to lina, and returns a copy of mili to make liste the list head.
The 3rd line follows the links until NULL is encountered, printing each name as it goes.
Last edited on
Super thanks a lot guys - thumbs up!
Topic archived. No new replies allowed.