Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Sub Linked List (http://www.velocityreviews.com/forums/t275944-sub-linked-list.html)

Jeff Cheng 07-23-2003 08:02 AM

Sub Linked List
 
Can anybody help to trace the runtime error for the following code
about sub-Linked list.

Thank you,


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

typedef char *CategoryType;
typedef char *ItemType;
typedef char *CodeType;
typedef int QtyType;

typedef struct node_item {
ItemType ItemDesc;
CodeType CodeNo;
QtyType Quantity;
node_item *NextItemLink;
} items;

typedef struct node_cat {
node_item *ItemLink;
CategoryType CatData;
node_cat *CatLink;
} category;


typedef category *CatPtr;
//typedef items *ItemLink;
typedef items *ItemLink;

void Initialise (CatPtr *L) {
*L = NULL;
}

// this is to add category
void AddCatNode (CatPtr *L, CategoryType x) {
CatPtr p, q;

p=(CatPtr) malloc (sizeof(category));
p->CatData = x;
p->CatLink = NULL;
if (*L == NULL)
*L = p;
else {
q = *L;
while (q->CatLink!=NULL)
q=q->CatLink;
q->CatLink = p;
}
}

// this is to add item
void AddItemNode (ItemLink *L, ItemType x, CodeType y, QtyType z) {
ItemLink p, q;

p=(ItemLink) malloc (sizeof(items));
p->ItemDesc = x;
p->CodeNo = y;
p->Quantity = z;
p->NextItemLink = NULL;
if (*L == NULL)
*L = p;
else {
q = *L;

//while (q->NextItemLink!=NULL)
// q=q->NextItemLink;
//q->NextItemLink = p;
}
}

//cat search
CatPtr SearchCatList (CatPtr L, CategoryType x) {
CatPtr p;
p = L;
while (p!=NULL) {
if (x == p->CatData)
return p;
else
p=p->CatLink;
}
return p;
}

//item search
ItemLink SearchItemList (ItemLink L, ItemType x) {
ItemLink p;
p = L;
while (p!=NULL) {
if (x == p->CodeNo)
return p;
else
p=p->NextItemLink;
}
return p;
}

//item display
void DisplayItemList (ItemLink L) {
ItemLink p;

for (p=L; p!=NULL; p=p->NextItemLink) {
printf("%s\n", p->ItemDesc);
printf("%s\n", p->CodeNo);
printf("%d\n", p->Quantity);
}
}



void main() {
CatPtr CatList,p;
ItemLink ItemList, i;
int choice, z;
char yn;
char *x, *y;


Initialise (&CatList);

do {

printf ("Main Menu\n");
printf ("1. Add Record\n");
printf ("2. Search\n");
printf ("3. Print\n");
printf ("9. Exit\n");
printf("\nPlease enter your choice> ");
scanf ("%d", &choice);

switch (choice) {
case 1:
printf ("Please select what you want to add\n");
printf ("1. Add Category\n");
printf ("2. Add Item\n");
printf ("Please enter your choice> ");
scanf ("%d", &choice);

// this is to add new category
if (choice == 1) {
printf ("Please key in New Category> ");
scanf ("%s", &x);
AddCatNode (&CatList, x);
}

// this is to add new item
if (choice == 2) {
printf ("Please key in Category> ");
scanf ("%s", &x);
p= SearchCatList (CatList, x);
if (p==NULL)
printf ("Category not found\n");
else {
printf ("Please enter the New Item> ");
scanf ("%s", &x);
printf ("Please enter the New Code> ");
scanf ("%s", &y);
printf ("Please enter the Quantity> ");
scanf ("%d", &z);
AddItemNode (&ItemList, x, y ,z);
}
}

break;


case 2:
printf ("Please Enter Category> ");
scanf("%s", &x);
p = SearchCatList (CatList, x);

printf ("Please Enter Code No> ");
scanf("%s", &y);
i = SearchItemList (ItemList, y);

if (i==NULL)
printf ("No such item");
else {
printf("%s", i->ItemDesc);
printf("%s", i->CodeNo);
printf("%d", i->Quantity);
}
break;

case 3:
printf ("Please enter your Category> ");
scanf ("%s", &x);

DisplayItemList (ItemList);
break;


//int tem;
//tem = 1;
//while (tem < 100000) {
// tem++;
printf("%s", &x);
//}


}
}while (choice !=9);

}

Karl Heinz Buchegger 07-23-2003 08:40 AM

Re: Sub Linked List
 


Jeff Cheng wrote:
>
> Can anybody help to trace the runtime error for the following code
> about sub-Linked list.


How about making your runtime error reproducable in the first place.
That means: write a new main, which is not dependent on user input
and is as short as possible.

If you start with that and step through the code you actually
*might* find the problem by yourself.

That's always the first thing in fighting a bug: make it reproducable!

>
> Thank you,
>
> # include <stdio.h>
> # include <stdlib.h>
>
> typedef char *CategoryType;
> typedef char *ItemType;
> typedef char *CodeType;
> typedef int QtyType;
>
> typedef struct node_item {
> ItemType ItemDesc;
> CodeType CodeNo;
> QtyType Quantity;
> node_item *NextItemLink;
> } items;
>
> typedef struct node_cat {
> node_item *ItemLink;
> CategoryType CatData;
> node_cat *CatLink;
> } category;
>
> typedef category *CatPtr;
> //typedef items *ItemLink;
> typedef items *ItemLink;
>
> void Initialise (CatPtr *L) {
> *L = NULL;
> }
>
> // this is to add category
> void AddCatNode (CatPtr *L, CategoryType x) {
> CatPtr p, q;
>
> p=(CatPtr) malloc (sizeof(category));


don't cast the return value of malloc. It may hide a
serious bug!

> p->CatData = x;


This just copies the pointer! Are you aware of that and have
you thought it through if this is really what you want to do?

[big snip while checking this ]

>
> void main() {


main returns int. Always!

> CatPtr CatList,p;
> ItemLink ItemList, i;
> int choice, z;
> char yn;
> char *x, *y;


x is a pointer to characters.

[snip]
> if (choice == 1) {
> printf ("Please key in New Category> ");
> scanf ("%s", &x);


Boom!
Where is the memory where scanf should write to?
Are you sure that the memory reserved for a character pointer
can hold your string?

Also: you promise to scanf by specifying %s, that the second argument will
be a character pointer, yet you pass a pointer to a character pointer. Those
don't fit.


eg.
x = malloc( 80 ); // allocate room for 80 characters
scanf( "%s", x );


I'll stop here.
May I suggest that before you continue your studies on data structures, that you
make yourself familiar with the way string handling works in C? There are lots
of pitfalls in that topic and it seems you trapped in every single on of them.

--
Karl Heinz Buchegger
kbuchegg@gascad.at

John Harrison 07-23-2003 10:28 AM

Re: Sub Linked List
 

"Jeff Cheng" <elkenjeff@hotmail.com> wrote in message
news:416984df.0307230002.4d6daf84@posting.google.c om...
> Can anybody help to trace the runtime error for the following code
> about sub-Linked list.
>
> Thank you,
>
>


What input produces the bug? Please, do a little bit of work yourself, to
help the group help you.

john



Alf P. Steinbach 07-23-2003 11:31 AM

Re: Sub Linked List
 
As Karl and John have already noted you need to do some
work yourself and provide the details.

However, as to the C _code_, why do you post C code in a
C++ group?




On 23 Jul 2003 01:02:20 -0700, elkenjeff@hotmail.com (Jeff Cheng) wrote:

>Can anybody help to trace the runtime error for the following code
>about sub-Linked list.
>
>Thank you,
>
>
># include <stdio.h>


That should be

#include <cstdio>

_if_ that header was required. But these facilities are not, in
general, type safe. So at your current level you should not use
them for anything -- use <iostream> instead.


># include <stdlib.h>


That should be


#include <cstdlib>


_if_ that header were required (which it isn't).


>typedef char *CategoryType;
>typedef char *ItemType;
>typedef char *CodeType;


Yes it is a good idea to name things. No it isn't a good
idea to represent these types as the same type. If they have
different functionality, e.g. restrictions on the set of
valid values, capture that by using proper classes.

Also, it's absolutely not a good idea to use char* even where
you only need a string of characters.

Use std::string instead, so as to avoid allocation and
deallocation bugs.



>typedef int QtyType;


Yes it is a good idea to name things. No it isn't a good
idea to hide the direct representation as int behind a
name. Use a class, or use plain int.



>typedef struct node_item {
> ItemType ItemDesc;
> CodeType CodeNo;
> QtyType Quantity;
> node_item *NextItemLink;
>} items;


In C++ that would be


struct node_item {
itemType ItemDesc;
CodeType CodeNo;
QtyType Quantity;
node_item *NextItemLink;
};

typedef node_item items;


But what is it you imagine that you need the typedef for?

It's _not_ a good idea to introduce aliases for type names.




>typedef struct node_cat {
> node_item *ItemLink;
> CategoryType CatData;
> node_cat *CatLink;
>} category;


Ditto.




>typedef category *CatPtr;
>//typedef items *ItemLink;
>typedef items *ItemLink;
>
>void Initialise (CatPtr *L) {
> *L = NULL;
>}


Use a constructor for initialization.



>// this is to add category
>void AddCatNode (CatPtr *L, CategoryType x) {
> CatPtr p, q;
>
> p=(CatPtr) malloc (sizeof(category));


Don't use malloc. In C++ use 'new'.


> p->CatData = x;
> p->CatLink = NULL;
> if (*L == NULL)
> *L = p;
> else {
> q = *L;
> while (q->CatLink!=NULL)
> q=q->CatLink;
> q->CatLink = p;
> }
> }
>
>// this is to add item
>void AddItemNode (ItemLink *L, ItemType x, CodeType y, QtyType z) {
> ItemLink p, q;
>
> p=(ItemLink) malloc (sizeof(items));
> p->ItemDesc = x;
> p->CodeNo = y;
> p->Quantity = z;
> p->NextItemLink = NULL;
> if (*L == NULL)
> *L = p;
> else {
> q = *L;
>
> //while (q->NextItemLink!=NULL)
> // q=q->NextItemLink;
> //q->NextItemLink = p;
> }
> }


Indentation, indentation, indentation.




>//cat search
>CatPtr SearchCatList (CatPtr L, CategoryType x) {
> CatPtr p;
> p = L;
> while (p!=NULL) {
> if (x == p->CatData)
> return p;
> else
> p=p->CatLink;
> }
> return p;
> }
>
>//item search
>ItemLink SearchItemList (ItemLink L, ItemType x) {
> ItemLink p;
> p = L;
> while (p!=NULL) {
> if (x == p->CodeNo)
> return p;
> else
> p=p->NextItemLink;
> }
> return p;
> }
>
>//item display
>void DisplayItemList (ItemLink L) {
> ItemLink p;
>
> for (p=L; p!=NULL; p=p->NextItemLink) {
> printf("%s\n", p->ItemDesc);
> printf("%s\n", p->CodeNo);
> printf("%d\n", p->Quantity);
> }
>}
>
>
>
>void main() {


Invalid in both C and C++. Should be


int main()





> CatPtr CatList,p;
> ItemLink ItemList, i;
> int choice, z;
> char yn;
> char *x, *y;
>
>
> Initialise (&CatList);
>
> do {
>
> printf ("Main Menu\n");
> printf ("1. Add Record\n");
> printf ("2. Search\n");
> printf ("3. Print\n");
> printf ("9. Exit\n");
> printf("\nPlease enter your choice> ");
> scanf ("%d", &choice);
>
> switch (choice) {
> case 1:
> printf ("Please select what you want to add\n");
> printf ("1. Add Category\n");
> printf ("2. Add Item\n");
> printf ("Please enter your choice> ");
> scanf ("%d", &choice);
>
> // this is to add new category
> if (choice == 1) {
> printf ("Please key in New Category> ");
> scanf ("%s", &x);
> AddCatNode (&CatList, x);
> }
>
> // this is to add new item
> if (choice == 2) {
> printf ("Please key in Category> ");
> scanf ("%s", &x);
> p= SearchCatList (CatList, x);
> if (p==NULL)
> printf ("Category not found\n");
> else {
> printf ("Please enter the New Item> ");
> scanf ("%s", &x);
> printf ("Please enter the New Code> ");
> scanf ("%s", &y);
> printf ("Please enter the Quantity> ");
> scanf ("%d", &z);
> AddItemNode (&ItemList, x, y ,z);
> }
> }
>
> break;
>
>
> case 2:
> printf ("Please Enter Category> ");
> scanf("%s", &x);
> p = SearchCatList (CatList, x);
>
> printf ("Please Enter Code No> ");
> scanf("%s", &y);
> i = SearchItemList (ItemList, y);
>
> if (i==NULL)
> printf ("No such item");
> else {
> printf("%s", i->ItemDesc);
> printf("%s", i->CodeNo);
> printf("%d", i->Quantity);
> }
> break;
>
> case 3:
> printf ("Please enter your Category> ");
> scanf ("%s", &x);
>
> DisplayItemList (ItemList);
> break;
>
>
> //int tem;
> //tem = 1;
> //while (tem < 100000) {
> // tem++;
> printf("%s", &x);
> //}
>
>
> }
> }while (choice !=9);
>
>}


The number of lines in main is unacceptable. Keep it down to
something that can be grokked at a glance.




All times are GMT. The time now is 10:05 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.