|
|
View previous topic :: View next topic |
Author |
Message |
t90
Joined: 07 Aug 2008 Posts: 11 Location: saigon,vietnam
|
problem with Linked-List |
Posted: Mon Sep 22, 2008 10:34 pm |
|
|
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
|
|
Posted: Tue Sep 23, 2008 2:12 am |
|
|
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
|
|
Posted: Tue Sep 23, 2008 2:44 am |
|
|
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
|
|
Posted: Wed Sep 24, 2008 1:55 am |
|
|
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
|
|
Posted: Wed Sep 24, 2008 2:35 am |
|
|
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. |
|
|
|
|
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
|