|
Home > Archive > Unix Programming > December 2006 > question on passing adresses/pointers
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 |
question on passing adresses/pointers
|
|
|
| Hi everyone,
A question if you will;
I have a function (the load_event function):
GLint load_events(GLvoid)
{
FILE *fp;
GLint test_char;
events *tmp;
/* Open event database for reading */
if((fp=fopen(EVENTS,"r"))==NULL) {
fprintf(stderr,"load_events: Could not open events for reading\n");
perror("fopen");
return(1); }
/* Allocate memory for tmp struct ptr */
for(;;) {
if((tmp=malloc(sizeof(*tmp)))==NULL) {
fprintf(stderr,"load_events: Could not allocate memory for node\n");
perror("malloc");
return(1);}
/* Properly set next pointer */
tmp->next=NULL;
if(read_e_member(tmp->timestamp,fp)||
__ _read_e_member(tmp->hostname,fp)||
__ _read_e_member(tmp->event,fp)||
__ _read_e_member(tmp->red,fp)||
__ _read_e_member(tmp->green,fp)||
__ _read_e_member(tmp->blue,fp)||
__ _read_e_member(tmp->alpha,fp)==NULL) {
fprintf(stderr,"load_events: Could not load members succesfully\n");
perror("load_events");
_ _ clean_memory(e_tail!=NULL ? e_head : tmp);
_ _ return(1); }
/* Add event into memory */
add_event(0,tmp->red,tmp->green,tmp->blue,tmp->alpha,tmp->timestamp,tmp->hostname,tmp->event);
/*
Clean memory */
clean_memory(tmp);
/* Test if we reached the end of the file - if yes we're done,
otherwise push the character back into the input stream */
_ _ if((test_char=fgetc(fp))==EOF) break;
else ungetc(test_char,fp);
}
fclose(fp);
return(0);
}
If i pass it the yet uninitialized members of tmp, and i malloc them
within read_e_member, once i get back to the load_event function,
should the tmp members be readable or not? Because it seems to me, when
i pass a uninitialized member of tmp to read_e_member (which has
prototype read_e_member(GLchar *member) that although member will get a
proper address to point to (once malloced), it's scope is only local,
and once i get back a member of tmp still points to garbage. Is this
assumption correct? Or am i actually passing the _address_ to the
function in which case_they should be readable.
Thanks
| |
| Barry Margolin 2006-12-21, 7:25 pm |
| In article <458afa81$0$322$e4fe514c@news.xs4all.nl>,
atv <alef@xs4all.nl> wrote:
> Hi everyone,
> A question if you will;
>
> I have a function (the load_event function):
> GLint load_events(GLvoid)
> {
> FILE *fp;
> GLint test_char;
> events *tmp;
>
> /* Open event database for reading */
> if((fp=fopen(EVENTS,"r"))==NULL) {
> fprintf(stderr,"load_events: Could not open events for reading\n");
> perror("fopen");
> return(1); }
>
> /* Allocate memory for tmp struct ptr */
> for(;;) {
> if((tmp=malloc(sizeof(*tmp)))==NULL) {
> fprintf(stderr,"load_events: Could not allocate memory for node\n");
> perror("malloc");
> return(1);}
>
> /* Properly set next pointer */
> tmp->next=NULL;
>
> if(read_e_member(tmp->timestamp,fp)||
> __ _read_e_member(tmp->hostname,fp)||
> __ _read_e_member(tmp->event,fp)||
> __ _read_e_member(tmp->red,fp)||
> __ _read_e_member(tmp->green,fp)||
> __ _read_e_member(tmp->blue,fp)||
> __ _read_e_member(tmp->alpha,fp)==NULL) {
> fprintf(stderr,"load_events: Could not load members succesfully\n");
> perror("load_events");
> _ _ clean_memory(e_tail!=NULL ? e_head : tmp);
> _ _ return(1); }
>
> /* Add event into memory */
>
> add_event(0,tmp->red,tmp->green,tmp->blue,tmp->alpha,tmp->timestamp,tmp->hostn
> ame,tmp->event);
>
> /*
>
> Clean memory */
> clean_memory(tmp);
> /* Test if we reached the end of the file - if yes we're done,
> otherwise push the character back into the input stream */
>
> _ _ if((test_char=fgetc(fp))==EOF) break;
> else ungetc(test_char,fp);
> }
>
> fclose(fp);
> return(0);
> }
>
>
>
> If i pass it the yet uninitialized members of tmp, and i malloc them
> within read_e_member, once i get back to the load_event function,
> should the tmp members be readable or not? Because it seems to me, when
> i pass a uninitialized member of tmp to read_e_member (which has
> prototype read_e_member(GLchar *member) that although member will get a
> proper address to point to (once malloced), it's scope is only local,
> and once i get back a member of tmp still points to garbage. Is this
> assumption correct? Or am i actually passing the _address_ to the
> function in which case_they should be readable.
Your original assumption is correct. You need to pass the member
addresses explicitly, e.g.
read_e_member(&tmp->red, fp)
The declaration of the function should be read_e_member(GLchar **member,
FILE *fp), and after it mallocs the data it should assign *member=ptr.
--
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 ***
| |
|
| >>
>
> Your original assumption is correct. You need to pass the member
> addresses explicitly, e.g.
> read_e_member(&tmp->red, fp)
>
> The declaration of the function should be read_e_member(GLchar
> **member, FILE *fp), and after it mallocs the data it should assign
> *member=ptr.
Thanks Barry,
That's what i thought. Because i got garbage when i tried to
dereference the pointers once the function read_e_member returned,
although i had malloced them inside there and i had passed a pointer
for it to malloc to.
Could you tell me:
1. Why i need to explicitly pass the addresses. Is it normally not
sufficient when passing a address of one pointer to another to just do
ptr=ptr ?
2. Why do i need to change GLchar *member to a pointer to a pointer?
3. I'm not sure what you mean by 'after it mallocs the data it should
assign the *member =ptr' either, unless you mean that i store the
returned pointer from malloc into member, which seems obvious.
Thanks for helping.
Kind regards,
Alef
| |
| matevzb 2006-12-22, 7:29 am |
| On Dec 22, 11:07 am, atv <a...@xs4all.nl> wrote:
>
>
> That's what i thought. Because i got garbage when i tried to
> dereference the pointers once the function read_e_member returned,
> although i had malloced them inside there and i had passed a pointer
> for it to malloc to.
>
> Could you tell me:
> 1. Why i need to explicitly pass the addresses. Is it normally not
> sufficient when passing a address of one pointer to another to just do
> ptr=ptr ?
> 2. Why do i need to change GLchar *member to a pointer to a pointer?
> 3. I'm not sure what you mean by 'after it mallocs the data it should
> assign the *member =ptr' either, unless you mean that i store the
> returned pointer from malloc into member, which seems obvious.
Here's an analogy without pointers:
void fcn (int a, int b)
{
b = a;
}
int i = 10, j = 5;
fcn (i, j);
What is now the value of j? It's still 5, since fcn() only got a _copy_
of j and changed its value (not j's).
With pointers:
void fcn (char *a, char *b)
{
b = a;
}
char *p1 = <whatever>, *p2 = NULL;
fcn (p1, p2);
Still the same, p1 and p2 are _copies_ local to the fcn(), so p2 wasn't
changed.
If you do this however:
void fcn (char *a, char **b)
{
*b = a;
}
char *p1 = <whatever>, *p2 = NULL;
fcn (p1, &p2);
p2 will now point to wherever p1 is pointing.
Hope this answers all of your questions...
--
WYCIWYG - what you C is what you get
| |
|
| >> <snip>
> Here's an analogy without pointers:
> void fcn (int a, int b)
> {
> b = a;
> }
>
> int i = 10, j = 5;
> fcn (i, j);
> What is now the value of j? It's still 5, since fcn() only got a _copy_
> of j and changed its value (not j's).
>
> With pointers:
> void fcn (char *a, char *b)
> {
> b = a;
> }
> char *p1 = <whatever>, *p2 = NULL;
> fcn (p1, p2);
> Still the same, p1 and p2 are _copies_ local to the fcn(), so p2 wasn't
> changed.
>
> If you do this however:
> void fcn (char *a, char **b)
> {
> *b = a;
> }
> char *p1 = <whatever>, *p2 = NULL;
> fcn (p1, &p2);
> p2 will now point to wherever p1 is pointing.
>
> Hope this answers all of your questions...
Kinda. I'll have to do some studying on your last function though :-)
Thanks!
| |
| matevzb 2006-12-22, 1:17 pm |
| On Dec 22, 5:34 pm, atv <a...@xs4all.nl> wrote:
> Kinda. I'll have to do some studying on your last function though :-)
> Thanks!
C passes arguments to functions by value, so the called function cannot
change the original variable. But, if you pass a pointer to the value,
the function now gets the location in memory where the value is stored
and it can write something else into that location by dereferencing
that pointer:
void fcn (int a, int *b) /* b is a pointer to the location where the
value is stored */
{
/* dereference b, copy a's value into b's memory */
*b = a;
}
When the variable in question is itself a pointer, you need to pass
_its_ pointer to the called function, so that's a pointer to a pointer.
Hope this is clearer, I'm not that good at explaining this... =)
I also noticed that this is probably wrong:
if(read_e_member(tmp->timestamp,fp)||
read_e_member(tmp->hostname,fp)||
read_e_member(tmp->event,fp)||
read_e_member(tmp->red,fp)||
read_e_member(tmp->green,fp)||
read_e_member(tmp->blue,fp)||
read_e_member(tmp->alpha,fp)==NULL)
I believe you want to check whether NULL is returned for each call to
read_e_member(), not just the last one.
--
WYCIWYG - what you C is what you get
|
|
|
|
|