Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Pointers/Structures/Functions - LOST :( 1

Status
Not open for further replies.

DanWiFi

Programmer
Jul 7, 2004
7
US
Hi guys, I must admit I am sort of a newbie to C, so bear with me.

I have this pointer to a structure:

struct pool *dpa;

declared outside of main (making it global, I believe).

now I need to pass this pointer down 3 functions where the third function will need to mess with the data in the structure the pointer points to. Example:

/* call the first function and send the pointer to it */

First_Function(&dpa);

int First_Function(struct pool *pointer)
{
Second_Function(&pointer);
}

int Second_Function(struct pool *pointerTwo)
{
Third_Function(&pointerTwo);
}

int Third_Function(struct pool *pointerThree)
{

*pointerThree->somemember = somethingelse;
}



My question is, am I doing this right? Am I passing the pointer correctly? Am I accessing the structure correctly in the third function? The reason I am asking, is that it doesn't seem to be working this way.

I have seen things like instead of declaring struct pool *variable in the function parameters some people use struct pool **variable. I am not sure how to access the pointer to the struct to pass it on after that though...

Any help / clarification would be very much appreciated.

Thanks!
DanWiFi
 
Hi DanWiFi ,
your variable dpa is already a pointer. so when you call firstfunction, you need to simply pass the variable.

Code:
 First_Function(dpa);

"First_Function(&dpa); " , as u wrote it would pass the
address of a variable, which you have already declared
as a pointer. Passing in &dpa would mean that you are
passing in the address of a pointer variable, which
I am sure you did not intend to do.
Again, the variable that has come into first_function is already a pointer variable and hence you simply need to pass this onto the functions
so your calls would look lke this

Code:
int First_Function(struct pool *pointer)
 {
      Second_Function(pointer);
 }

int Second_Function(struct pool *pointerTwo)
 {
      Third_Function(pointerTwo);
 }

int Third_Function(struct pool *pointerThree)
 {
     pointerThree->somemember = somethingelse;
 }

 
My functions don't return anything because this is just example code not real code.

I am trying to emulate someone else's code. Let me show you the real code that they are using:

/* in the test.h area they have: */
struct dpoolm_t; /* Forward declaration */

/* create the structures for the hash table - obviously based off of the code in Chillispot */


struct dpool_t {
int listsize; /* Total number of addresses */
struct dpoolm_t *member; /* Listsize array of members */
int hashsize; /* Size of hash table */
int hashlog; /* Log2 size of hash table */
int hashmask; /* Bitmask for calculating hash */
struct dpoolm_t **hash; /* Hashsize array of pointer to member */
};

struct dpoolm_t {
struct in_addr addr; /* IP address of this member in the table */
struct dpoolm_t *nexthash; /* Linked list part of hash table */
};


/* now in the test.c global area they have: */
struct dpool_t *dpa;


/* in the main function they have : */

processdomains(args_info.alloweddomains_arg, &dpa);


/* here is the function for that */

int processdomains(char *domains, struct dpool_t **this)
{

char **arry;
char **doms; /* List of IPS returned from the gethostbyname */
char *dom; /*single IP */

struct hostent *he;
int i=0, Count, C=0, j=0;



Count = Split(domains, (char *)",", &arry);


/* hash table stuff - the size of the table */
unsigned int listsize;

/* allow size for the ip addresses in the table */
listsize = Count * 10; /* allows for X amount domains with 10 ips behind each. should be enough. */

if (!(*this = calloc(sizeof(struct dpool_t), 1))) {
/* Failed to allocate memory for dpool */
return -1;
}

(*this)->listsize += listsize;

/* more code that is irrelevant to my question */

return 0;
}




So my question is ------- why does he use the struct dpool_t **this right there???? what use is it? This code works, By the way. I however, don't understand its mechanics, and was trying to repeat it.

DanWiFi
 
OK, now let me try to explain this. Do ask if I am not clear enough.
The code you just pasted above is FINE. Because
it says

Code:
struct dpool_t *dpa;

followed by
Code:
processdomains(args_info.alloweddomains_arg, &dpa);
.
.
.
int processdomains(char *domains, struct dpool_t **this)

This works because dpa itself is a pointer to type struct dpool_t. This code passes in the call to processdomains a pointer to dpa itself. This means that the function processdomains should expect
"pointer to (type of dpa)"
which means
pointer to (pointer to struct dpool_t)
or a (double pointer to dpool_t)
and NOT
(pointer to dpool_t)

This is borne out by the fact that the function processdomains
takes as its second parameter
"struct dpool_t **this"
which is a double pointer to dpool_t

Now, what you tried to do in your initial post was
First_Function(&dpa);

which means you were passing a (pointer to dpa)
which is a (double pointer to pool)
but your function First_Function expected a single pointer to pool
Code:
int First_Function(struct pool *pointer)
 {
      Second_Function(&pointer);
 }
Note that the way I did it in my post,
I used single pointers only.
So you either use double pointers as the code above does, or single pointers as I did.

Hope this makes things a bit clearer :)
Again, do reply if you need any clarification
regards,
rajesh.
 
hmm ok that makes sense - but why would one use the more complicated double pointer method over the easier single pointer method?

I am doing all of this because, using the code above that I gave you, I need to pass struct dpool_t *dpa down two functions, andthen pass a single pointer to a third - and I don't know exactly how to do that.

Would I go :

struct dpool_t *dpa;

/* call to the process domains is the same as above code */

/* but then I need to pass that dpool structure down */

First_Function(&dpa);

First_Function(struct dpool_t **dpaOne)
{
/* passed into first, now pass it on to second */
Second_Function(&dpaOne);
}

Second_Function(struct dpool_t **dpaTwo)
{
/* passed into second, now I need to send the third
function the dpool structure itself, unlike
all of the other functions */
Third_Function(dpaTwo);
}

/* the third function is setup to take the following */

Third_Function(struct dpool_t *dpaThree, struct in_addr *addr)
{
dpaThree->member = somevariable;
}

god pointers are confusing! :) but thank you for your help!

DanWiFi
 
yep...pointers are confusing ..very true :)
lemme answer your second q first
abt how to pass dpa to the third function
not that tough
Now you have a variable
dpaTwo, in the function Second_Function
and you need to pass it onto Third_Function, but as a single pointer
you simply dereference it
As u might recall, the unary "*" can be used to dereference a pointer variable, or in other words, it gives you the variable pointed to by the operand.
Hence in Second_Function, your call would look like this

Third_Function(*dpaTwo);

So dpaTwo being (pointer to pointer to type dpool_t)
this call would take away one level of addressing, to put it simply, and pass in
(pointer to type dpool_t) to Third_Function
So now alls in place.
Hope that helps w.r.t how to do it.
Now, about why double pointers are reqd, there are scenarios where double pointers are certainly reqd. From this snippet of the code itself, it aint sure to me why its needed here tho.
All the best,
Rajesh.

 
ahh ok - I do understand, but I think I am missing something.

When I use the pointer to pointer code method below, I receive "warning: passing argument 1 of Second_Function from incompatible pointer type"

struct dpool_t *dpa;

First_Function(&dpa);

First_Function(struct dpool_t **dpaOne)
{
/* passed into first, now pass it on to second */
Second_Function(&dpaOne);
}

Second_Function(struct dpool_t **dpaTwo)
{
/* passed into second, now I need to send the third
function the dpool structure itself, unlike
all of the other functions */
Third_Function(*dpaTwo);
}

/* the third function is setup to take the following */

Third_Function(struct dpool_t *dpaThree, struct in_addr *addr)
{
dpaThree->member = somevariable;
}
 
Code:
First_Function(struct dpool_t **dpaOne)
{
      /* passed into first, now pass it on to second */
      Second_Function(&dpaOne);
}

Second_Function(struct dpool_t **dpaTwo)

in this above snippet, you dont need to pass &dpaOne to Second_Function as it is already a double pointer. You can simply make do with dpaOne.
Hope thats helpful.
 
ahh ok that makes all the warnings go away.

I still have a problem where when i run the code, I get a segmentation fault or a bus error (seems to be random which one appears) on the call to the third function.

Would you be able to take a look at my code if I sent it to you? I know I am asking a lot, and I appreciate all the time you have put in on this. I haven't got a darn clue as to why, other than I THINK I am still not passing the structure / pointers correctly. My email address is dstrohschein at thewifilink dot com - send me an email and I will send the code I am working on to that email.

Thanks
DanWifi
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top