|
Home > Archive > Unix Programming > November 2006 > strange problem with ptr in linked list
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
strange problem with ptr in linked list
|
|
|
| I am setting upon initialization of program the head and tail pointers
both to NULL.
then, in a function where i add nodes to it, i check with:
database *search=head; /* set to beginning */
while(search!=NULL)
but it returns true upon first calling the function.
what is happening here?
any idea's would be most welcome
| |
| Pascal Bourguignon 2006-11-17, 7:30 am |
| atv <alef@xs4all.nl> writes:
> I am setting upon initialization of program the head and tail pointers
> both to NULL.
> then, in a function where i add nodes to it, i check with:
>
> database *search=head; /* set to beginning */
> while(search!=NULL)
>
> but it returns true upon first calling the function.
>
> what is happening here?
>
> any idea's would be most welcome
So, you are doing:
% cd /tmp/ ; cat a.c
#include <stdio.h>
typedef int database;
int main(void){
database* head=NULL;
database* tail=NULL;
database* search=head;
printf("start\n");
while(search!=NULL){
printf("search is not null\n");
}
printf("fini\n");
return(0);
}
% gcc a.c -o a ; ./a
start
fini
%
and you don't get the same result?
--
__Pascal Bourguignon__ http://www.informatimago.com/
HEALTH WARNING: Care should be taken when lifting this product,
since its mass, and thus its weight, is dependent on its velocity
relative to the user.
| |
|
| On 2006-11-17 13:40:29 +0100, Pascal Bourguignon <pjb@informatimago.com> said:
> typedef int database;
> int main(void){
> database* head=NULL;
> database* tail=NULL;
> database* search=head;
> printf("start\n");
> while(search!=NULL){
> printf("search is not null\n");
> }
> printf("fini\n");
> return(0);
> }
Sorry, my bad. I looked at it the wrong way :-). I need to get some
fresh air :-P
thanks though. However, the problem with a ptr seems still there. It
eithers gets a SIGBUS or a SIGV
This is the code i use, i commented it so it's function is clear. I
hope you will take a look at it. I think myself that that either the
while loop is searching to far and the subsequent strcmp function is
crashing it. At least, that's what gdb would like me to believe.
Gr,
Alef
--
GLvoid add_database(database *tmp)
{
database *search=head; /* Reset search pointer to first node */
database *nextptr=NULL;/* This saves the next pointer so we do not break
the link when replacing the struct ptr. */
/* First find the node. Update if it exists, add if it does not */
while(search!=NULL) {
if(!strcmp(tmp->hostname,search->hostname)) {
fprintf(stderr,"Node updated");
nextptr=search->next; /* Save the next pointer of the current node */
*search=*tmp; /* Replace the struct with updated information */
search->next=nextptr; /* Set the replaced struct with the saved next ptr */
return 0;}
search=search->next;}
if(tail==NULL) {
if((tail=malloc(sizeof(*tail)))==NULL) {
fprintf(stderr,"Could not allocate memory for node\n");
perror("malloc");
exit(1);}
*tail=*tmp; /* Replace node with passed ptr [already filled in] */
tail->next=NULL;
head=tail;
object_count++;}
else {
if((tail->next=malloc(sizeof(*tail)))==NULL) {
fprintf(stderr,"Could not allocate memory for node\n");
perror("malloc");
exit(1);}
tail=tail->next;
*tail=*tmp; /* Replace node with passed ptr [already filled in] */
tail->next=NULL;
object_count++;}
}
| |
|
| atv wrote:
> GLvoid add_database(database *tmp)
> {
> database *search=head; /* Reset search pointer to first node */
> database *nextptr=NULL;/* This saves the next pointer so we do not
> break
> the link when replacing the struct ptr. */
>
> /* First find the node. Update if it exists, add if it does not */
> while(search!=NULL) {
I see you are initializing search to head, but how did you initialize
head? Most likely it is wrongly initialized.
> if(tail==NULL) {
Write like this:
if ( NULL == tail ) {
less likely to make errors like:
if ( tail = NULL ) {
| |
| Pascal Bourguignon 2006-11-17, 1:22 pm |
| atv <alef@xs4all.nl> writes:
> Sorry, my bad. I looked at it the wrong way :-). I need to get some
> fresh air :-P
> thanks though. However, the problem with a ptr seems still there. It
> eithers gets a SIGBUS or a SIGV
>
> This is the code i use, i commented it so it's function is clear. I
> hope you will take a look at it. I think myself that that either the
> while loop is searching to far and the subsequent strcmp function is
> crashing it. At least, that's what gdb would like me to believe.
Assuming the _*COMPLETE*_ program as follow, it works perfectly well.
-*- mode: compilation; default-directory: "/tmp/" -*-
Compilation started at Fri Nov 17 15:51:03
cd /tmp/ ; cat a.c ; gcc a.c -o a ; ./a un deux trois deux quatre un quatre cinq
#include <stdio.h>
#include <stdlib.h>
typedef struct database {
char* hostname;
struct database* next;
} database;
database* head=0;
database* tail=0;
int object_count=0;
int add_database(database *tmp)
{
database *search=head; /* Reset search pointer to first node */
database *nextptr=NULL;/* This saves the next pointer so we do not break
the link when replacing the struct ptr. */
/* First find the node. Update if it exists, add if it does not */
while(search!=NULL) {
if(!strcmp(tmp->hostname,search->hostname)) {
fprintf(stderr,"Node updated\n");
nextptr=search->next; /* Save the next pointer of the current node */
*search=*tmp; /* Replace the struct with updated information */
search->next=nextptr; /* Set the replaced struct with the saved next ptr */
return 0;}
search=search->next;}
if(tail==NULL) {
if((tail=malloc(sizeof(*tail)))==NULL) {
fprintf(stderr,"Could not allocate memory for node\n");
perror("malloc");
exit(1);}
*tail=*tmp; /* Replace node with passed ptr [already filled in] */
tail->next=NULL;
head=tail;
object_count++;}
else {
if((tail->next=malloc(sizeof(*tail)))==NULL) {
fprintf(stderr,"Could not allocate memory for node\n");
perror("malloc");
exit(1);}
tail=tail->next;
*tail=*tmp; /* Replace node with passed ptr [already filled in] */
tail->next=NULL;
object_count++;}
}
void dump_database(void){
database* current=head;
printf("head = %08x\n",head);
while(current!=0){
printf("%08x . hostname = \"%s\"\n",current,current->hostname);
printf("%08x . next = %08x\n",current,current->next);
current=current->next;}
printf("tail = %08x\n",tail);}
int main(int argc,char** argv){
int i;
dump_database();
for(i=1;i<argc;i++){
database tmp;
tmp.next=0;
tmp.hostname=argv[i];
add_database(&tmp);
dump_database();}
return(0);}
head = 00000000
tail = 00000000
head = 0804a050
0804a050 . hostname = "un"
0804a050 . next = 00000000
tail = 0804a050
head = 0804a050
0804a050 . hostname = "un"
0804a050 . next = 0804a060
0804a060 . hostname = "deux"
0804a060 . next = 00000000
tail = 0804a060
head = 0804a050
0804a050 . hostname = "un"
0804a050 . next = 0804a060
0804a060 . hostname = "deux"
0804a060 . next = 0804a070
0804a070 . hostname = "trois"
0804a070 . next = 00000000
tail = 0804a070
Node updated
head = 0804a050
0804a050 . hostname = "un"
0804a050 . next = 0804a060
0804a060 . hostname = "deux"
0804a060 . next = 0804a070
0804a070 . hostname = "trois"
0804a070 . next = 00000000
tail = 0804a070
head = 0804a050
0804a050 . hostname = "un"
0804a050 . next = 0804a060
0804a060 . hostname = "deux"
0804a060 . next = 0804a070
0804a070 . hostname = "trois"
0804a070 . next = 0804a080
0804a080 . hostname = "quatre"
0804a080 . next = 00000000
tail = 0804a080
Node updated
head = 0804a050
0804a050 . hostname = "un"
0804a050 . next = 0804a060
0804a060 . hostname = "deux"
0804a060 . next = 0804a070
0804a070 . hostname = "trois"
0804a070 . next = 0804a080
0804a080 . hostname = "quatre"
0804a080 . next = 00000000
tail = 0804a080
Node updated
head = 0804a050
0804a050 . hostname = "un"
0804a050 . next = 0804a060
0804a060 . hostname = "deux"
0804a060 . next = 0804a070
0804a070 . hostname = "trois"
0804a070 . next = 0804a080
0804a080 . hostname = "quatre"
0804a080 . next = 00000000
tail = 0804a080
head = 0804a050
0804a050 . hostname = "un"
0804a050 . next = 0804a060
0804a060 . hostname = "deux"
0804a060 . next = 0804a070
0804a070 . hostname = "trois"
0804a070 . next = 0804a080
0804a080 . hostname = "quatre"
0804a080 . next = 0804a090
0804a090 . hostname = "cinq"
0804a090 . next = 00000000
tail = 0804a090
Compilation finished at Fri Nov 17 15:51:03
--
__Pascal_Bourguignon__ _ Software patents are endangering
() ASCII ribbon against html email (o_ the computer industry all around
/\ 1962:DO20I=1.100 //\ the world http://lpf.ai.mit.edu/
2001:my($f)=`fortune`; V_/ http://petition.eurolinux.org/
| |
|
| On 2006-11-17 15:51:27 +0100, Pascal Bourguignon <pjb@informatimago.com> said:
>
Thanks Pascal,
I will take a long hard look at the code and compare. In the meantime,
2 questions:
1. If i do a sizeof(database *) do i get the total size of the struct
(including all data in there) or just the size of all the variables
_or_ do i get the size i malloced for it.
2. How can i tell, when using shared memory, that i put a struct in
there. For example, in another function i did *data=*tmp where data is
the ptr to shared memory and tmp is the struct i put in there.
How can i determine if i put it in there. I can't just do if(data)
because it will point to the shm so that's good.
Any thoughts?
| |
| Pascal Bourguignon 2006-11-17, 1:22 pm |
| atv <alef@xs4all.nl> writes:
> On 2006-11-17 15:51:27 +0100, Pascal Bourguignon <pjb@informatimago.com> said:
>
> Thanks Pascal,
> I will take a long hard look at the code and compare. In the meantime,
> 2 questions:
>
> 1. If i do a sizeof(database *) do i get the total size of the struct
> (including all data in there) or just the size of all the variables
> _or_ do i get the size i malloced for it.
Assuming database is a typedef, database* is a pointer. The size of
the database type in general is irrelevant to the size of the pointer.
(In some strange architectures or strange C++ situations, a pointer
may need more than an address, but this is really exotic).
> 2. How can i tell, when using shared memory, that i put a struct in
> there. For example, in another function i did *data=*tmp where data is
> the ptr to shared memory and tmp is the struct i put in there.
>
> How can i determine if i put it in there. I can't just do if(data)
> because it will point to the shm so that's good.
I don't understand your question? If it's good what's the problem?
--
__Pascal Bourguignon__ http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we. -- Georges W. Bush
| |
| Barry Margolin 2006-11-17, 1:22 pm |
| In article <455ddecb$0$338$e4fe514c@news.xs4all.nl>,
atv <alef@xs4all.nl> wrote:
> On 2006-11-17 15:51:27 +0100, Pascal Bourguignon <pjb@informatimago.com> said:
>
> Thanks Pascal,
> I will take a long hard look at the code and compare. In the meantime,
> 2 questions:
>
> 1. If i do a sizeof(database *) do i get the total size of the struct
> (including all data in there) or just the size of all the variables
> _or_ do i get the size i malloced for it.
It returns the size of the struct, including any padding. It doesn't
include the size of other structures that are pointed to by members of
the struct.
> 2. How can i tell, when using shared memory, that i put a struct in
> there. For example, in another function i did *data=*tmp where data is
> the ptr to shared memory and tmp is the struct i put in there.
>
> How can i determine if i put it in there. I can't just do if(data)
> because it will point to the shm so that's good.
There's no automatic way to do this. You could have a field in the
structure that indicates whether it's valid. The shared memory will
start with everything set to 0. If this field in *tmp contains 1, you
can then do if(data->valid).
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
|
|
|
|
|