473,289 Members | 2,108 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,289 software developers and data experts.

Linked List problem.

Ben
Hi,

I am a newbie with C and am trying to get a simple linked list working
for my program. The structure of each linked list stores the char
*data and *next referencing to the next link. The problem I get is
that I am trying to link a struct that I have defined and its refusing
to link. I have tried casting my struct into char * but attempts to
cast it back to its original struct to access its contents only seg
faults.

I'd attempt to change the type of data in the linked list to that my
struct but that just doesnt seem right.
Any advice is appreciated.

Thanks
Ben
Nov 14 '05 #1
10 2473

"Ben" <be******@hotmail.com> wrote in message
news:87**************************@posting.google.c om...
Hi,

I am a newbie with C and am trying to get a simple linked list working
for my program. The structure of each linked list stores the char
*data and *next referencing to the next link. The problem I get is
that I am trying to link a struct that I have defined and its refusing
to link. I have tried casting my struct into char * but attempts to
cast it back to its original struct to access its contents only seg
faults.

I'd attempt to change the type of data in the linked list to that my
struct but that just doesnt seem right.
Any advice is appreciated.


Your bug is on line 42.

-Mike
Nov 14 '05 #2
be******@hotmail.com (Ben) writes:
I am a newbie with C and am trying to get a simple linked list working
for my program. The structure of each linked list stores the char
*data and *next referencing to the next link. The problem I get is
that I am trying to link a struct that I have defined and its refusing
to link. I have tried casting my struct into char * but attempts to
cast it back to its original struct to access its contents only seg
faults.

I'd attempt to change the type of data in the linked list to that my
struct but that just doesnt seem right.
Any advice is appreciated.

First, don't do any casting. Casting is unnecessary for coding a
simple linked list, and if casting is unnecessary it usually is best
to avoid it.
Second, start with defining the type, perhaps something like this:

typedef struct node_struct_tag *List, ListElement;

struct node_struct_tag {
char *data;
List next;
};
Now, a simple function:

unsigned int
list_length( List head_of_list ){
List remainder; unsigned int result;

remainder = head_of_list;
result = 0;

while( remainder != 0 ){
result++;
remainder = remainder->next;
}

return result;
}
A function for list formation:

List
lisp_style_cons( char *value, List tail ){
List result;

result = malloc( sizeof( *result ) );
assert( result != 0 );

result->data = value;
result->next = tail;

return result;
}
A function for more typical C-style manipulation:

void
splice_one_element_into_list( List element, List *list_address ){
assert( list_address != 0 );
assert( element != 0 );

element->next = *list_address;
*list_address = element;
}
That function might be used in a function that inserts into
a sorted list:

void
insert_into_sorted_list( List element, List *sorted_list_address ){
List *insertion_point;

assert( element != 0 );
assert( sorted_list_address != 0 );

insertion_point = sorted_list_address;
while( *insertion_point != 0 ){
if( strcmp( (*insertion_point)->data, element->data ) > 0 ){
break;
}
insertion_point = & (*insertion_point)->next;
}

splice_one_element_into_list( element, insertion_point );
}
Before trying to compile this code, read through it and make sure
you understand what you think it's doing and why.

If you want to try compiling, first find the appropriate headers for
assert(), malloc() and strcmp(), and #include them.

The functions above almost certainly aren't what you want, but if
you can understand these you should be able to write the functions
that you do want.

Disclaimer: the code above has not been compiled or even syntax
checked (except manually by myself). I'm confident the many
readers of the NG will graciously report any bonehead errors
I've made. :)
Nov 14 '05 #3


Tim Rentsch wrote:
be******@hotmail.com (Ben) writes:

I am a newbie with C and am trying to get a simple linked list working
for my program. The structure of each linked list stores the char
*data and *next referencing to the next link. The problem I get is
that I am trying to link a struct that I have defined and its refusing
to link. I have tried casting my struct into char * but attempts to
cast it back to its original struct to access its contents only seg
faults.

I'd attempt to change the type of data in the linked list to that my
struct but that just doesnt seem right.
Any advice is appreciated.


typedef struct node_struct_tag *List, ListElement;

struct node_struct_tag {
char *data;
List next;
};


....snip....
List
lisp_style_cons( char *value, List tail ){
List result;

result = malloc( sizeof( *result ) );
assert( result != 0 );

result->data = value;
result->next = tail;

return result;
}

....snip...

Disclaimer: the code above has not been compiled or even syntax
checked (except manually by myself). I'm confident the many
readers of the NG will graciously report any bonehead errors
I've made. :)


I haven't noticed in bonehead errors but function lisp_style_cons,
listed above, scares me. The function requires that 'value'
point to storage allocated somewhere else. I prefer to encapsulate
the allocation and assignment in the function that creates the node.
Examples below:

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

typedef struct NODE
{
char *data;
struct NODE *next;
} NODE;

unsigned NodesInList( NODE *p );
int AddListHead( NODE **p, const char *s );
int AddListTail( NODE **p, const char *s );
void PrintList( NODE *p );
void FreeList( NODE **p );

int main(void)
{
NODE *head = NULL;

AddListTail(&head,"Hello World");
AddListTail(&head,"Goodbye World");
AddListHead(&head,"The list head");
printf("There are %u Nodes in the list.\n",
NodesInList(head));
PrintList(head);
FreeList(&head);
printf("\nFreed the list. Now there are %u "
"nodes in the list.\n",NodesInList(head));
return 0;
}

unsigned NodesInList( NODE *p )
{
unsigned nelem;

for(nelem = 0; p; p = p->next,nelem++) ;
return nelem;
}

int AddListHead( NODE **p, const char *s )
{
NODE *new;

if((new = malloc(sizeof *new)) == NULL) return 0;
if((new->data = malloc(strlen(s)+1)) == NULL)
{
free(new);
return 0;
}
strcpy(new->data,s);
new->next = *p;
*p = new;
return 1;
}

int AddListTail( NODE **p, const char *s )
{
NODE **tmp, *new;

if((new = malloc(sizeof *new)) == NULL) return 0;
if((new->data = malloc(strlen(s)+1)) == NULL)
{
free(new);
return 0;
}
strcpy(new->data,s);
new->next = NULL;
for(tmp = p; *tmp != NULL;tmp = &(*tmp)->next) ;
*tmp= new;
return 1;
}

void PrintList( NODE *p )
{
unsigned i;

for(i = 1 ; p; p = p->next,i++)
printf("Node %u: Data is \"%s\"\n",i,p->data);
return;
}

void FreeList( NODE **p )
{
NODE *tmp;

for( ; *p; *p = tmp)
{
tmp = (*p)->next;
free((*p)->data);
free(*p);
}
return;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #4
Ben
Hello,

Dont quite understand how your code fixes my query.
I already have a working, linkedlist.c. I know it works because I have
tested it using strings as data.
My linkedlist has the following struct

struct link {
char *data
link *next
}
#excluding respective typedef statements

#enqueue adds a new element to list
enqueue(*link, char *data)

In my main.c program.
I have another structure which i want to put into a linked list

struct people {
char *name
int *age
char *address
}

Now I have included my linkedlist.c into my main.c
However I cant do enqueue(peoplelist, *newpeople)
where peoplelist is a *link and *newpeople is a people
because gcc complains that it wants char instead of people

and enqueue(peoplelist, (char *) newpeople) only gives me
*name when i try to access the element again (because of the string
terminator?). It also wont let me cast it back to (people) and wont
let me access within newpeople (eg newpeople.age).

I was wondering if there was a way to allow linkedlist to use people
as an element but without changing the struct link's char *data to
people *data
Is this possible or is there another better solution?

Tim Rentsch <tx*@alumnus.caltech.edu> wrote in message news:<kf*************@alumnus.caltech.edu>...
be******@hotmail.com (Ben) writes:
I am a newbie with C and am trying to get a simple linked list working
for my program. The structure of each linked list stores the char
*data and *next referencing to the next link. The problem I get is
that I am trying to link a struct that I have defined and its refusing
to link. I have tried casting my struct into char * but attempts to
cast it back to its original struct to access its contents only seg
faults.

I'd attempt to change the type of data in the linked list to that my
struct but that just doesnt seem right.
Any advice is appreciated.

First, don't do any casting. Casting is unnecessary for coding a
simple linked list, and if casting is unnecessary it usually is best
to avoid it.
Second, start with defining the type, perhaps something like this:

typedef struct node_struct_tag *List, ListElement;

struct node_struct_tag {
char *data;
List next;
};
Now, a simple function:

unsigned int
list_length( List head_of_list ){
List remainder; unsigned int result;

remainder = head_of_list;
result = 0;

while( remainder != 0 ){
result++;
remainder = remainder->next;
}

return result;
}
A function for list formation:

List
lisp_style_cons( char *value, List tail ){
List result;

result = malloc( sizeof( *result ) );
assert( result != 0 );

result->data = value;
result->next = tail;

return result;
}
A function for more typical C-style manipulation:

void
splice_one_element_into_list( List element, List *list_address ){
assert( list_address != 0 );
assert( element != 0 );

element->next = *list_address;
*list_address = element;
}
That function might be used in a function that inserts into
a sorted list:

void
insert_into_sorted_list( List element, List *sorted_list_address ){
List *insertion_point;

assert( element != 0 );
assert( sorted_list_address != 0 );

insertion_point = sorted_list_address;
while( *insertion_point != 0 ){
if( strcmp( (*insertion_point)->data, element->data ) > 0 ){
break;
}
insertion_point = & (*insertion_point)->next;
}

splice_one_element_into_list( element, insertion_point );
}
Before trying to compile this code, read through it and make sure
you understand what you think it's doing and why.

If you want to try compiling, first find the appropriate headers for
assert(), malloc() and strcmp(), and #include them.

The functions above almost certainly aren't what you want, but if
you can understand these you should be able to write the functions
that you do want.

Disclaimer: the code above has not been compiled or even syntax
checked (except manually by myself). I'm confident the many
readers of the NG will graciously report any bonehead errors
I've made. :)

Nov 14 '05 #5


Ben wrote:
Hello,

Dont quite understand how your code fixes my query.
I already have a working, linkedlist.c. I know it works because I have
tested it using strings as data.
My linkedlist has the following struct

struct link {
char *data
link *next
}
#excluding respective typedef statements

#enqueue adds a new element to list
enqueue(*link, char *data)
This doesn't look right. You need to provide the definition
of function enqueue plus code on how you use it. Provide actual
code, not pseudo code.

In my main.c program.
I have another structure which i want to put into a linked list

struct people {
char *name
int *age
char *address
}

Now I have included my linkedlist.c into my main.c
However I cant do enqueue(peoplelist, *newpeople)
where peoplelist is a *link and *newpeople is a people
because gcc complains that it wants char instead of people

and enqueue(peoplelist, (char *) newpeople) only gives me
*name when i try to access the element again (because of the string
terminator?). It also wont let me cast it back to (people) and wont
let me access within newpeople (eg newpeople.age).
It will not let you because it is erroneous.

I was wondering if there was a way to allow linkedlist to use people
as an element but without changing the struct link's char *data to
people *data
Is this possible or is there another better solution?


The solution requires you to change your struct link.

Perhaps:

struct link
{
struct people data;
struct link *next;
};

or
struct link
{
struct people *data;
struct link *next;
};

Then rewrite function enqueue and other functions that manipulates
the link list. A simple cast will not work.

Example:

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

struct people
{
char *name;
unsigned age;
char *address;
};

typedef struct NODE
{
struct people data;
struct NODE *next;
} NODE;

unsigned NodesInList( NODE *p );
int enqueue( NODE **p, const char *name, unsigned age,
const char *addr );
void PrintList( NODE *p );
void FreeList( NODE **p );

int main(void)
{
NODE *head = NULL;

enqueue(&head,"George Washington",46,
"2000 Adams Blvd\nWashington DC");
enqueue(&head,"Bill Clinton", 43,
"152 E. Hickory Ave\nLittle Rock, AR");
enqueue(&head,"George Bush",37,
"1401 Vine St\nHouston, TX");
printf("There are %u Nodes in the list.\n\n",
NodesInList(head));
PrintList(head);
FreeList(&head);
printf("\nFreed the list. Now there are %u "
"nodes in the list.\n",NodesInList(head));
return 0;
}

unsigned NodesInList( NODE *p )
{
unsigned nelem;

for(nelem = 0; p; p = p->next,nelem++) ;
return nelem;
}

int enqueue( NODE **p, const char *name, unsigned age,
const char *addr )
{
NODE **tmp, *new;

if((new = malloc(sizeof *new)) == NULL) return 0;
if((new->data.name = malloc(strlen(name)+1)) == NULL)
{
free(new);
return 0;
}
if((new->data.address = malloc(strlen(addr)+1)) == NULL)
{
free(new->data.name);
free(new);
return 0;
}
strcpy(new->data.name, name);
strcpy(new->data.address, addr);
new->data.age = age;
new->next = NULL;
for(tmp = p; *tmp != NULL;tmp = &(*tmp)->next) ;
*tmp= new;
return 1;
}

void PrintList( NODE *p )
{
unsigned i;

for(i = 1 ; p; p = p->next,i++)
printf("Node %u:\n%s Age %u\n%s\n\n",i,p->data.name,
p->data.age, p->data.address);
return;
}

void FreeList( NODE **p )
{
NODE *tmp;

for( ; *p; *p = tmp)
{
tmp = (*p)->next;
free((*p)->data.name);
free((*p)->data.address);
free(*p);
}
return;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #6
Al Bowers <xa******@rapidsys.com> writes:
Tim Rentsch wrote:
[some cutting here]
List
lisp_style_cons( char *value, List tail ){
List result;

result = malloc( sizeof( *result ) );
assert( result != 0 );

result->data = value;
result->next = tail;

return result;
}

[some cutting here]


I haven't noticed in bonehead errors but function lisp_style_cons,
listed above, scares me. The function requires that 'value'
point to storage allocated somewhere else. I prefer to encapsulate
the allocation and assignment in the function that creates the node.
[Example code omitted]


I take your point. What is the "right" way to do storage allocation
in C is a non-trivial topic, and the pattern shown above certainly
isn't typical. I thought it would help illustrate a linked-list
function that the person asking the question might be familiar with
and so be helpful in that way. The storage allocations issues were
definitely glossed over in my posting, so as not to overcomplicate the
example.
Nov 14 '05 #7
be******@hotmail.com (Ben) writes:
Hello,

Dont quite understand how your code fixes my query.
I already have a working, linkedlist.c. I know it works because I have
tested it using strings as data.
My linkedlist has the following struct

struct link {
char *data
link *next
}
#excluding respective typedef statements

#enqueue adds a new element to list
enqueue(*link, char *data)

In my main.c program.
I have another structure which i want to put into a linked list

struct people {
char *name
int *age
char *address
}

Now I have included my linkedlist.c into my main.c
However I cant do enqueue(peoplelist, *newpeople)
where peoplelist is a *link and *newpeople is a people
because gcc complains that it wants char instead of people

and enqueue(peoplelist, (char *) newpeople) only gives me
*name when i try to access the element again (because of the string
terminator?). It also wont let me cast it back to (people) and wont
let me access within newpeople (eg newpeople.age).

I was wondering if there was a way to allow linkedlist to use people
as an element but without changing the struct link's char *data to
people *data
Is this possible or is there another better solution?


If you've been reading comp.lang.c for a while then you know that
people with questions are told to post actual code rather than
summaries or descriptions. And, if the actual code is lots of lines,
to prepare an example as reasonably small as they can that still
demonstrates the problem they want to ask about.

There are various reasons for doing this, some having to do with
courtesy and politeness, some having to do with NG readers being able
to actually supply an answer, and some having to do with maximizing
*your* value from any answers you might get.

A. Working on preparing the posting might let you see the answer
yourself. That's more valuable to you than if it has to be explained.

B. "[gcc] won't let me cast it back." The problem with this statement
is almost everyone reading it won't know what you mean. Of course,
the few readers of CLC who are true mindreaders will, but they
generally don't like posting answers. [:)]

C. I appreciate that you probably think you're making it easier on
people by posting only a short description rather than some long code
body, etc. Most readers, though, are frustrated because they don't
have enough information to answer the question, and it seems obvious
to them that there isn't enough information to answer the question.
So, to really make it easier for the readers, put in the time to get
*real code* that illustrates the problem in as short a space as
you can.

Based on what you wrote, it seems clear that you're confused
about _something_ related to casting and/or pointers; beyond
that, I'm not going to guess.

Oh, one more thing - I think I'd be remiss if I didn't put in
a reminder to read the comp.lang.c FAQ for starters. I'm sure
these points must be covered in there somewhere.
Nov 14 '05 #8
send the code you're trying to run (or better - a simplified version
that exhibits the problems you're having). it's impossible to help
unless we know where you're coming from.

Nov 14 '05 #9
Ben
"Mike Deskevich" <mi***********@gmail.com> wrote in message news:<10**********************@z14g2000cwz.googleg roups.com>...
send the code you're trying to run (or better - a simplified version
that exhibits the problems you're having). it's impossible to help
unless we know where you're coming from.


Thanks to all who have been advising and sorry for the long overdue reply.
My question is all about casting and pointers and what conditions allow it.

Please correct my following assumptions,

1) Int can be casted into a char
int i=0;
char a;
a=(char *) i;
2) Structure casted into an array of char
typedef struct {
char name[20];
int age;
int id;
} person;

person p = (person *) malloc(sizeof(person));
p.name="hello";
p.age=2;
p.id=2;

char *a;
a=(char *)p;
Nov 14 '05 #10
be******@hotmail.com (Ben) wrote:
Please correct my following assumptions,

1) Int can be casted into a char
int i=0;
char a;
a=(char *) i;
This is confused. _Either_ you assign an int to a char, in which case
you don't need the cast (and the cast as written is wrong), _or_ you
assign it to a char * (and the declaration of a is wrong), in which
case:
Yes, you can, but the result is not necessarily meaningful. It may not
be a valid pointer at all; it may not point to memory you can write to
or even read; and even when it does, it may not point where you expect
it to point. In particular, in the above example, a need _not_ be a null
pointer.
At least a char * is always correctly aligned. Had a been an int *, for
example, it might have been an incorrectly aligned pointer.
2) Structure casted into an array of char
typedef struct {
char name[20];
int age;
int id;
} person;

person p = (person *) malloc(sizeof(person));
p.name="hello";
p.age=2;
p.id=2;

char *a;
a=(char *)p;


No. You cannot cast a struct into a pointer. And what would you do this
for, anyway? Do you suppose that the bytes represented by "hello"
somehow form a valid pointer?
I suspect you meant to access the struct itself _through_, not _as_, a
pointer to char. In that case, you need to do

a = (char *)&p;

which is perfectly legal, and can be useful - though rarely. Beware the
padding bytes!

Richard
Nov 14 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
by: RAJASEKHAR KONDABALA | last post by:
Hi, Does anybody know what the fastest way is to "search for a value in a singly-linked list from its tail" as oposed to its head? I am talking about a non-circular singly-linked list, i.e.,...
5
by: John N. | last post by:
Hi All, Here I have a linked list each containing a char and is double linked. Then I have a pointer to an item in that list which is the current insertion point. In this funtion, the user...
7
by: Kieran Simkin | last post by:
Hi all, I'm having some trouble with a linked list function and was wondering if anyone could shed any light on it. Basically I have a singly-linked list which stores pid numbers of a process's...
57
by: Xarky | last post by:
Hi, I am writing a linked list in the following way. struct list { struct list *next; char *mybuff; };
3
by: Little | last post by:
Could someone tell me what I am doing wrong here about declaring mutiple double linked lists. This is what the information is for the project and the code wil be below that. Thank your soo much for...
11
by: bofh1234 | last post by:
Hello, I am having a problem with linked lists. My program is based on a client server model. The client sends some packets of data to the server. The server reads those packets and is...
22
by: joshc | last post by:
In an interview for an embedded software position recently I was asked to write code, in C, for printing the contents of a linked list backwards. After a few minutes I came up with the recursive...
23
by: Himanshu Chauhan | last post by:
Hi! I was wondering, In the first parse of a singly linked list of unknown length, is it possible to know when we are at middle of the linked list? Regards --Himanshu
7
by: QiongZ | last post by:
Hi, I just recently started studying C++ and basically copied an example in the textbook into VS2008, but it doesn't compile. I tried to modify the code by eliminating all the templates then it...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.