472,971 Members | 1,949 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Is this a valid data structure??

Dan
I'm trying to creat a data structure, that can be either a integer,
double, string, or linked list. So I created the following, but don't
know if it is the data structure itself causing problems, or something
I am doing in the rest of the program.

This is the data structure.

struct node
{
char type;
union data
{
int integer;
double number;
char* word;
struct node* list;
}data;

struct node *next;
};
And this is the program I am using it in.

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

struct node
{
char type;
union data
{
int integer;
double number;
char* word;
struct node* list;
}data;

struct node *next;
};

typedef struct node node;
typedef struct node* node_ptr;
node_ptr new_node(char type);
void add_node(node_ptr destination, node_ptr source);
void print_node(node_ptr value);

int main()
{
node_ptr A;
node_ptr B;
node_ptr C;
node_ptr D;

A=new_node('I');
A->data.integer = 1;
printf("%i ", A->data.integer);

B=new_node('S');
B->data.word = "Hello";
printf("%s ", B->data.word);

C=new_node('D');
C->data.number = 1.567;
printf("%f ", C->data.number);

D=new_node('L');
add_node (D,A);
print_node(D);
}
node_ptr new_node(char type)
{
node_ptr ret_ptr = (node_ptr) malloc (sizeof(node));
ret_ptr->type = type;
switch (toupper(type))
{
case 'I':

ret_ptr->data.integer=0;
break;

case 'D':

ret_ptr->data.number=0;
break;

case 'S':

ret_ptr->data.word = "";
break;

case 'L':

ret_ptr->data.list = NULL;
break;

default:

printf("Error");
return NULL;
}

ret_ptr->next = NULL;
return ret_ptr;
}

void add_node(node_ptr destination, node_ptr source)
{
node_ptr next_ptr;
node_ptr prev_ptr;
printf("%c ", destination->type);
if (destination->type =! 'L')
{
printf("Error");
return;
}
if (destination->data.list == NULL)
{
destination->data.list = source;
printf("%c ", destination->type);
return;
}
next_ptr = destination->data.list;
while (next_ptr->data.list != NULL)
{
prev_ptr = next_ptr;
next_ptr= next_ptr->next;
}

prev_ptr->next = next_ptr;
}
void print_node(node_ptr value)
{
if (value == NULL)
return;

printf("%c ",value->type);

switch (value->type)
{
case 'I':

printf("% i", value->data.integer);
break;

case 'D':
printf("% f", value->data.number);
break;

case 'S':
printf("% s", value->data.word);
break;

case 'L':
printf("[");
print_node(value->data.list);
printf("]");
break;

default:
printf("Error");
return;
}

print_node(value->next);
}

The bug is in add node with a list, 'L', why does it change the actual
node itself. Maybe I don't see the logic but why does this line

destination->data.list = source;

change the actual destination node itself to something else. It seems
to me it would just change the list data member in the inner union to
point to the source pointer. But it seems change the actual
destination pointer itself.

Arggh...C drives me nuts.

Any help would be appreciated.

Thanks,

Dan
Nov 13 '05 #1
4 2427
On Mon, 06 Oct 2003 20:33:06 -0700, Dan wrote:
I'm trying to creat a data structure, that can be either a integer,
double, string, or linked list. So I created the following, but don't
know if it is the data structure itself causing problems, or something
I am doing in the rest of the program.

This is the data structure.

struct node
{
char type;
union data
{
int integer;
double number;
char* word;
struct node* list;
}data;

struct node *next;
};
And this is the program I am using it in.

#include <stdio.h>
#include <malloc.h>
there is no <malloc.h> header. malloc() is declared in <stdlib.h>
so you can remove this.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct node
{
char type;
union data
{
int integer;
double number;
char* word;
struct node* list;
}data;

struct node *next;
};

typedef struct node node;
typedef struct node* node_ptr;
I think you're better off not typedefing pointers. It makes it harder
to read your code. It does solve the problem of putting the '*'s in
right place, but that can also be solved by putting each variable
declaration on a line by itself, which is good to do anyway.
node_ptr new_node(char type)
{
node_ptr ret_ptr = (node_ptr) malloc (sizeof(node));
node * ret_ptr = malloc(sizeof *ret_ptr);
void add_node(node_ptr destination, node_ptr source)
{
node_ptr next_ptr;
node_ptr prev_ptr;
printf("%c ", destination->type);
if (destination->type =! 'L')
I suspect this is the problem you are talking about. It should be

if (destination->type != 'L')

You really should turn on all of the warnings on your compiler to
help you catch this sort of thing. If they are already on, then stop
ignoring them.
if (destination->data.list == NULL)
{
destination->data.list = source;
printf("%c ", destination->type);
return;
}
This looks fine
next_ptr = destination->data.list;
while (next_ptr->data.list != NULL)
{
prev_ptr = next_ptr;
next_ptr= next_ptr->next;
}

prev_ptr->next = next_ptr;
Big problems here. First, I assume you want to tack the struct
pointed to by 'source' onto the end of the list, but 'source' doesn't
ever appear in this piece of code, so that will never work.

Second, you appear to be confusing your 'head of list' pointer with
your 'link' pointers. destination->data.list is supposed to point
at the first element in a linked list, but presumably you mean to
use next_ptr->next to link the elements in the list.

Third, you don't need a previous pointer for a singly linked list
like this.

Look at this replacement code. notice that the new elements are
simply linked onto the end of the list using the 'next' pointer.

next_ptr = destination->data.list;
while (next_ptr->next != NULL)
next_ptr = next_ptr->next;

next_ptr->next = source;

void print_node(node_ptr value)
{ ... case 'L':
printf("[");
print_node(value->data.list);
printf("]");
break;


this will only print out the value of the first element of the
list. You can write a loop to traverse the list as above, or
simply recurse (assuming the list isn't too long) like this:

case 'L':
printf("[");
print_node(value->data.list); /* print this node */
print_node(value->next); /* print the next node */
printf("]");
break;

-Sheldon
Nov 13 '05 #2
Dan
Sheldon Simms <sh**********@yahoo.com> wrote in message news:<pa**************************@yahoo.com>...
On Mon, 06 Oct 2003 20:33:06 -0700, Dan wrote:
I'm trying to creat a data structure, that can be either a integer,
double, string, or linked list. So I created the following, but don't
know if it is the data structure itself causing problems, or something
I am doing in the rest of the program.

This is the data structure.

struct node
{
char type;
union data
{
int integer;
double number;
char* word;
struct node* list;
}data;

struct node *next;
};
And this is the program I am using it in.

#include <stdio.h>
#include <malloc.h>
there is no <malloc.h> header. malloc() is declared in <stdlib.h>
so you can remove this.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct node
{
char type;
union data
{
int integer;
double number;
char* word;
struct node* list;
}data;

struct node *next;
};

typedef struct node node;
typedef struct node* node_ptr;


I think you're better off not typedefing pointers. It makes it harder
to read your code. It does solve the problem of putting the '*'s in
right place, but that can also be solved by putting each variable
declaration on a line by itself, which is good to do anyway.
node_ptr new_node(char type)
{
node_ptr ret_ptr = (node_ptr) malloc (sizeof(node));


node * ret_ptr = malloc(sizeof *ret_ptr);
void add_node(node_ptr destination, node_ptr source)
{
node_ptr next_ptr;
node_ptr prev_ptr;
printf("%c ", destination->type);
if (destination->type =! 'L')


I suspect this is the problem you are talking about. It should be

if (destination->type != 'L')


Oh thanks for spotting this. That is the kind of bug that would have
me pulling my hair out.
You really should turn on all of the warnings on your compiler to
help you catch this sort of thing. If they are already on, then stop
ignoring them.
if (destination->data.list == NULL)
{
destination->data.list = source;
printf("%c ", destination->type);
return;
}


This looks fine
next_ptr = destination->data.list;
while (next_ptr->data.list != NULL)
{
prev_ptr = next_ptr;
next_ptr= next_ptr->next;
}

prev_ptr->next = next_ptr;


Big problems here. First, I assume you want to tack the struct
pointed to by 'source' onto the end of the list, but 'source' doesn't
ever appear in this piece of code, so that will never work.

Second, you appear to be confusing your 'head of list' pointer with
your 'link' pointers. destination->data.list is supposed to point
at the first element in a linked list, but presumably you mean to
use next_ptr->next to link the elements in the list.

Third, you don't need a previous pointer for a singly linked list
like this.

Look at this replacement code. notice that the new elements are
simply linked onto the end of the list using the 'next' pointer.

next_ptr = destination->data.list;
while (next_ptr->next != NULL)
next_ptr = next_ptr->next;

next_ptr->next = source;

void print_node(node_ptr value)
{

...
case 'L':
printf("[");
print_node(value->data.list);
printf("]");
break;


this will only print out the value of the first element of the
list. You can write a loop to traverse the list as above, or
simply recurse (assuming the list isn't too long) like this:

case 'L':
printf("[");
print_node(value->data.list); /* print this node */
print_node(value->next); /* print the next node */
printf("]");
break;

-Sheldon


I was thinking that the recursive call at the end of the function
would take care of this. But you're suggestion is probably better.
Nov 13 '05 #3
On Tue, 07 Oct 2003 10:25:26 -0700, Dan wrote:
Sheldon Simms <sh**********@yahoo.com> wrote in message news:<pa**************************@yahoo.com>...
On Mon, 06 Oct 2003 20:33:06 -0700, Dan wrote:
> void add_node(node_ptr destination, node_ptr source)
> {
> node_ptr next_ptr;
> node_ptr prev_ptr;
> printf("%c ", destination->type);
> if (destination->type =! 'L')


I suspect this is the problem you are talking about. It should be

if (destination->type != 'L')


Oh thanks for spotting this. That is the kind of bug that would have
me pulling my hair out.


My compiler spotted it.

Nov 13 '05 #4
gi*****@aol.com (Dan) wrote:
> if (destination->type =! 'L')


I suspect this is the problem you are talking about. It should be

if (destination->type != 'L')


Oh thanks for spotting this. That is the kind of bug that would have
me pulling my hair out.


Format comparisons to constants with the constant first, as

if ('L' =! destination->type)

That will get an error from you compiler because it attempts
assignment to an improper lvalue, the constant 'L'. This also
works for the typo "=" where "==" was meant, though many
compilers can catch that one anyway.

Here are other examples,

if (0 != ioctl(...)) {

and

if (NULL == (fp = fopen(...))) {

--
Floyd L. Davidson <http://web.newsguy.com/floyd_davidson>
Ukpeagvik (Barrow, Alaska) fl***@barrow.com
Nov 13 '05 #5

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

Similar topics

3
by: Mike Jones | last post by:
need help with data structures.Looking for ways to start, sample code, anything Program description: Design and implement a Visual C++ .NET program that inserts values into a data...
17
by: piraticman | last post by:
Hi. I have some code for a javascript jump menu... It validated with HTML 4.0 but now does not validate with XHTML strict 1.0. I have used name atributes in my code which aparantly are not...
2
by: Michael Kuzminski | last post by:
I have some xml from a company that usees the same xml tag underneath different nodes. The xml is valid, but ADO.net complains when I try to load it into a dataset. It gives me the error: ...
0
by: BobTheHacker | last post by:
I have a c# class library that I call to centralize some code amongst projects. It returns an arraylist back to the calling function that contains class data. Anyway when I call it I can receive it...
9
by: rsine | last post by:
I have developed a program that sends a command through the serial port to our business system and then reads from the buffer looking for a number. Everything worked great on my WinXP system, but...
3
by: DDF | last post by:
I took this snippet from a book I foudn online. Public Class Demo Public Structure ValueDemo Public X As Integer End Structure Public Class RefDemo Public Y As Integer End Class Public...
7
by: copx | last post by:
How do you implement an event queue in C? The problem I had is that events needed pointers to the objects they affect and I do not know any way to check if pointers are actually valid in C. The...
14
by: ml_sauls | last post by:
I've built a system to enter and manage purchase orders. This is in use by >10 clients. Some use it in Access 97, most are in A2k. About half use it through a Citrix implementation. It is...
4
by: Simple Simon | last post by:
It's entirely possible that I'm completely in the wrong line of work, but I don't see what Valgrind is complaining about in this code. Invalid read/writes? If I free the within main(), rather...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

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.