Sign in to follow this  
kingpinzs

How do I use a struct as a data type in a linked list class

Recommended Posts

how do I use a struct as a data type?

example

struct user
{
string name;
int id;
};

template<class Item>

class node
{
public:
typedef Item value_type;

node(const value_type& init_data = value_type(),const node* init_link = NULL)
{
data_field = init_data; link_field = init_link;
}
private:
value_type data_field;
node *link_field;
};

user p ;
p.name = "ted";
p.id =12;
node<user> *head_ptr;

now I want head_ptr to pust user p into the list

not sure how I can do this

Share this post


Link to post
Share on other sites
setting the node to int works but changeing it to a string makes it fail

int main()
{

node<string> *head_ptr; //just makes it crash with no warning or errors
node<int>*head_ptr;//works fine
head_ptr->set_data("12");
head_ptr->set_data(12);
head_ptr->set_link(NULL);
cout<<(*head_ptr).data();

return 0;
}

return 0;
}

Share this post


Link to post
Share on other sites
Both versions of your code should crash, or similar. You've made a pointer to a node, but you never actually make any nodes.[code]node<int>*head_ptr;//let's make a pointer variable. Pointers hold the addresses of other variables.
//Oh, the above pointer isn't initialised to anything... that means it could be pointing anywhere in memory
head_ptr->set_data("12");//lets take our random pointer and de-reference it
//Oh, undefined behaviour... this usually causes a crash[/code]
If you just want to use a list (without learning how to actually write a list), you can use std::list:[code]std::list<std::string> stringList;
std::list<int> intList;
stringList.push_back("12");
intList.push_back(12);[/code]

Share this post


Link to post
Share on other sites
I am trying to make a linked list from scratch.

by default the first node is null


head_ptr->set_data(12);
cout<<(*head_ptr).data();

shows 12 for output;

but
head_ptr->set_data("12");
cout<<(*head_ptr).data();

creats a windows error report;


Share this post


Link to post
Share on other sites
just like hodgman said. The pointer isn't set to any allocated area, thus using that pointer is ub and may crash your program. Or it may be pointing to somewhere in memory which makes it look like it works.

Share this post


Link to post
Share on other sites
What you're doing at the moment is analogous to this:[code]char* something = "this is a piece of text, somewhere in memory";//this is someone elses memory

int* danger = (int*)(something + 12);//we make a new pointer variable, and it's pointing at someone elses memory

*danger = 12;//lets trash their data by writing '12' over the top of it
cout << *danger;//look it "worked"!!
cout << something;//oh! oh...[/code]

You can't just make a pointer like this:
[font="Courier New"]node<user> *head_ptr;[/font]
and then use it immediately like this:
[font="Courier New"]head_ptr->whatever();[/font]

If you do, then you're doing something like in my code snippet! [font="Courier New"]head_ptr[/font] has not been given any address to point to, but by invoking "[font="Courier New"]->[/font]", you're using that undefined address!! It looks like it's working, but you're trashing memory which could cause a crash at any time. You're just lucky that it doesn't crash with the int, but that in no way means that your code is correct -- it's a memory-corrupting crash waiting to happen.

In order to use your pointers, you've actually got to create some nodes for them to point to:
[code]//either on the stack:
node<string> head, one, two;
head.set_link( &one );
one.set_link( &two );

//or on the heap:
node<string>* pHead = new node<string>;
node<string>* pOne = new node<string>;
pHead->set_link( pOne );

//or a mixture:
node<string> head;
node<string>* pOne = new node<string>;
head.set_link( pOne );[/code]but make sure you've learnt about memory leaks (every [font="Courier New"]new[/font] must be paired with a [font="Courier New"]delete[/font]) and scope rules for stack variables.

Share this post


Link to post
Share on other sites
[quote name='Hodgman' timestamp='1298347508' post='4777374']
What you're doing at the moment is analogous to this:[code]char* something = "this is a piece of text, somewhere in memory";//this is someone elses memory

int* danger = (int*)(something + 12);//we make a new pointer variable, and it's pointing at someone elses memory

*danger = 12;//lets trash their data by writing '12' over the top of it
cout << *danger;//look it "worked"!!
cout << something;//oh! oh...[/code]

You can't just make a pointer like this:
[font="Courier New"]node<user> *head_ptr;[/font]
and then use it immediately like this:
[font="Courier New"]head_ptr->whatever();[/font]

If you do, then you're doing something like in my code snippet! [font="Courier New"]head_ptr[/font] has not been given any address to point to, but by invoking "[font="Courier New"]->[/font]", you're using that undefined address!! It looks like it's working, but you're trashing memory which could cause a crash at any time. You're just lucky that it doesn't crash with the int, but that in no way means that your code is correct -- it's a memory-corrupting crash waiting to happen.

In order to use your pointers, you've actually got to create some nodes for them to point to:
[code]//either on the stack:
node<string> head, one, two;
head.set_link( &one );
one.set_link( &two );

//or on the heap:
node<string>* pHead = new node<string>;
node<string>* pOne = new node<string>;
pHead->set_link( pOne );

//or a mixture:
node<string> head;
node<string>* pOne = new node<string>;
head.set_link( pOne );[/code]but make sure you've learnt about memory leaks (every [font="Courier New"]new[/font] must be paired with a [font="Courier New"]delete[/font]) and scope rules for stack variables.
[/quote]


First that works thanks

Second how can I change it from string to a struct ?
struct user
{
user(string name, int id) : name(name), id(id) { };
string name;
int id;
};

Share this post


Link to post
Share on other sites
[quote name='Hodgman' timestamp='1298352567' post='4777403']
Replace "string" with your struct's name.
[/quote]


I did this
node<user>* pHead = new node<user>;
node<user>* pOne = new node<user>;
pHead->set_link( pOne );
pOne->set_data(p);

compiles and runs fine but

how do I call that data to be printed out?

I tryed
cout<<pOne;
and it gives me the address
tryed
cout<<*pOne;
just throughs error
no match for 'operator<<' in 'std::cout << * pOne'|
tryed
cout<<pOne.data();
get error
request for member 'data' in 'pOne', which is of non-class type 'node<user>*'|
Not sure what to try next

the code
const Item& data() const{return data_field;}
is what I am trying to call to return the data

Share this post


Link to post
Share on other sites
The error "[i]no match for 'operator<<' in 'std::cout << * pOne'[/i]" means you've not written a print function for the [font="Courier New"]node[/font] type.

The error, [i]"request for member 'data' in 'pOne', which is of non-class type 'node<user>*'"[/i] means that you used "." instead of "->".
"[font="Courier New"]pOne.data()[/font]" should be "[font="Courier New"]pOne[b]->[/b]data()[/font]"

but unless you've made a operator<< overload for the [font="Courier New"]user[/font] type, you'll have to access it's members too, like:
[font="Courier New"]cout<<pOne->data().name;[/font]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this