CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

problem with Linked-List

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
t90



Joined: 07 Aug 2008
Posts: 11
Location: saigon,vietnam

View user's profile Send private message Yahoo Messenger

problem with Linked-List
PostPosted: Mon Sep 22, 2008 10:34 pm     Reply with quote

I'm doing a graduating project about the Alarm clock. To implement this project I use the Linked list. There is no problem during compilation, no errors appear. But when I write the hex file into PIC 18F4680, it only inserts the 2nd Node into the List. If I continue to insert more Nodes, the compiler still accepts. However, when I display the value of Nodes in LCD, value of 3rd, 4th...the Node isn't the value I have inputted to it. Why can't my Linked-list work ?
Sorry about my English!
Here is my code:
Code:

#include "18f4680.h"
#device HIGH_INTS=TRUE
#use delay(clock=20000000)
#fuses HS,NOPROTECT,NOLVP,NODEBUG,NOWDT
#use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7)

#include <stdlibm.h>
#include <stddef.h>
//#include "LinkedLisv7.c"
#include "ewl_glcd.c"
#include "ewl_realtime.c"                                               

char glcd_buff[128];
char text1[]="Tra62n Quo61c Gia Phu1";
typedef enum Code{succ,equal,overflow} Error;
struct Node
{
  char tim[2];
  int index;
  struct Node *next;
};

struct Node *t;
struct Node *s;
struct Node *r;
char t1[2];
char t2[2];
char t3[2];
char t4[2];
char t5[2];
struct Node *a;
int1 flag=0;

void Delete( char X[2], List *L )
{
   struct Node *t1;
   struct Node *t2;
   //List rong
   if ( *L == NULL)
      return;
   t1=*L;
   //vi tri dau tien
   if( strcmp(X,t1->tim) == 0)
   {
      if( t1->next == NULL )
      {
         *L=NULL;
         return;
      }
      else
      {
         *L=*L->next;
         return;
      }   
   }
   t2 = t1->next;
   while((t2 != NULL)&(strcmp(X,t2->tim) >0))
   {
      t1 = t2;
      t2 = t2->next;
   }
   if(strcmp(X,t2->tim)==0)
   {
      if((t2->next) == NULL)
      {
         t1->next=NULL;
         return;
      }
      t1->next=t2->next;
      return;
   }
   retur
Error Insert( char X[2], struct Node *L )
{
   struct Node *t;
   struct Node *t1;
   struct Node *t2;
   t=(struct Node*)malloc( sizeof( struct Node ) );
   if( ( t == NULL ) )
      return overflow;
   t->next=NULL;
   strcpy( t->tim , X ); 
   //List rong
   if( L == NULL )
   {
      L=t;
      return succ;
   }
   t1=L;
   //neu la head
   if((strcmp(X,L->tim)) < 0)
   {
      L=t;
      L->next=t1;
        return succ;
   }
   //cac truong hop con lai
   t2 = t1->next;
   
    while((t2 != NULL))
   {
     if(strcmp(X,t2->tim) > 0)
     {
      t1 = t2;
      t2 = t2->next;
     }
     else
        break;
   }
   t1->next = t;
   t->next = t2;
   return succ;
}
void main()
{
   int key;
   
   char y[2];
   char z[2];
   char x[2];
   char w[2];
   char u[2];
   Error c;

 
   strcpy(y,"1");
   strcpy(z,"2");
   strcpy(x,"3");
   strcpy(w,"4");
   strcpy(u,"5");
   a= (struct Node*)malloc(sizeof(struct Node));
   t=a;
   strcpy(a->tim,"0");
   //strcpy(t1,t->tim);
   a->index=1;
   a->next=NULL;
   c=Insert(y,a);
 
   c=Insert(z,a);
   t=t->next;
   t=t->next;
   strcpy(t1,t->tim);

   if(strcmp(t1,t->tim)==0)
      strcpy(t2,"a");
   else
      strcpy(t2,"b");/**/
   set_tris_e(0x00);
   set_tris_d(0x00);
   set_tris_b(0xfc);
   set_tris_c(0b10000000);
   setup_adc(ADC_OFF);
   set_tris_a(0x00);
   ///////////////
   glcd_init(ON);
   glcd_fillScreen(OFF);
 
   set_tris_c(get_tris_c()&0b11111011);
   //setup_timer_2(T2_DIV_BY_16,127,1);
   //setup_timer_1(T2_DIV_BY_16,127,1);
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(500);
   
   //enable_interrupts(INT_EXT2);   
   enable_interrupts(GLOBAL);
   init_DS1307();
   
   set_tris_b(get_tris_b() | 0xF0);
   set_tris_e(0x00);
   while(1){
    /
      glcd_text57(0,30,t1,1,1);
 
   }
}
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Tue Sep 23, 2008 2:12 am     Reply with quote

First issue is you have global vars defined for t1, t2 etc and you use the same name in local vars as well! NOT good programming practise and may confuse anyone looking at it.

Secondly, your delete routine is wrong, you need to free the memory of the deleted item or your pic will eventually run out of ram. You also need to make the next pointer of the previous node (if ther is one) point to the node after the one that is found (If there is one) or point to null before returning. After a quick look at the code I could not see this.

Code:

 strcpy(t1,t->tim);

   if(strcmp(t1,t->tim)==0)
      strcpy(t2,"a");
   else
      strcpy(t2,"b");/**/

This should be pointless ans should always set t2 to "a". Does it ?
Where is the code which displays the nodes ?
Where is an example of your output ?

Another problem is you are passing the VALUE of you node pointer a to the insert routine. This may then modify the value of pointer L. This will not modify the pointer a to point to the new head, which is your intention, it will always point to the intial node it was assigned with. This should not affect adding to the end of the node which this code should be doing.

To fix it you need to pass the address of your node pointer to the routine so the routine can change it.

insert(&a);

insert (struct NODE **L);

You then need to use the L pointer corectly.

t1 = *L; // for instance will make t1 the same value as a.
*L = t; // will make a the same as t.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Sep 23, 2008 2:44 am     Reply with quote

Just another note:
Malloc is a great function on systems with lots of memory but on a tiny PIC processor it is better not used because malloc could lead to memory fragmentation. Best is to allocate memory just once and never free it again, or even better, use a static buffer.
t90



Joined: 07 Aug 2008
Posts: 11
Location: saigon,vietnam

View user's profile Send private message Yahoo Messenger

PostPosted: Wed Sep 24, 2008 1:55 am     Reply with quote

Thanks both of you. But, when I have just done as Wayne_ answer, the compiler report that "invalid type conversion":
Code:

Error Insert( char X[2], struct Node **L )
{
   Struct Node *t;
   Struct Node *t1;
   Struct Node *t2;
   t=(struct Node*)malloc( sizeof( struct Node ) );
   if( ( t == NULL ) )
      return overflow;
   t->next=NULL;
   strcpy( t->tim , X ); 
   //List rong
   if(*L == NULL)
   {
      (*L)=t;
      return succ;
   }
   t1=*L;
   //neu la head
   if((strcmp(X,*L->tim)) < 0)
   {
      (*L)=t;
      L->next=t1;
        return succ;
   }
   //cac truong hop con lai
   t2 = t1->next;
   
    while((t2 != NULL))
   {
     if(strcmp(X,t2->tim) > 0)
     {
      t1 = t2;
      t2 = t2->next;
     }
     else
        break;
   }
   t1->next = t;
   t->next = t2;
   return succ;
}
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Sep 24, 2008 2:35 am     Reply with quote

It appears that CCS does not cope with pointers to pointers.

Another way to do this is:-
Code:

typedef enum Code{succ,equal,overflow} Error;
struct Node
{
  char tim[2];
  int index;
  struct Node *next;
};

struct Head {
 struct Node *ptr;
};

struct Node *t;
struct Node *s;
struct Node *r;
//char t1[2];
//char t2[2];
//char t3[2];
//char t4[2];
//char t5[2];
struct Head *a;
int1 flag=0;

Error Insert( char X[2], struct Head *H ) {
   Struct Node *L;
   Struct Node *t;
   Struct Node *t1;
   Struct Node *t2;
   L = H->ptr;
   t=(struct Node*)malloc( sizeof( struct Node ) );
   if( ( t == NULL ) )
      return overflow;
   t->next=NULL;
   strcpy( t->tim , X );
   //List rong
   if (L == NULL) {
      H->ptr = t;
      return succ;
   }
   t1 = L;
   //neu la head
   if((strcmp(X,L->tim)) < 0) {
      t->next = H->ptr;
      H->ptr = t;
      return succ;
   }
   //cac truong hop con lai
   t2 = t1->next;

   while((t2 != NULL)) {
      if(strcmp(X,t2->tim) > 0) {
         t1 = t2;
         t2 = t2->next;
      } else
         break;
   }
   t1->next = t;
   t->next = t2;
   return succ;
}


You can then alter a->ptr to always point to the head of the list.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group