473,382 Members | 1,512 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Global pointer pointing to locally defined type

Hi!

What happens to a globally defined pointer, e.g.

void *value;

that points to a particular type in a function:

int dummy_func (int a)
{
value = &a;
return 0;
}

after the function returns to main? If this doesn't work, how could I make
it work? Do I have to allocate memory for this int and copy the original
int to that and then point value to this newly allocated int?

Thanks for your time,

Andrej
Nov 14 '05 #1
31 2128
Andrej Prsa <an*********@guest.arnes.si> scribbled the following:
Hi! What happens to a globally defined pointer, e.g. void *value; that points to a particular type in a function: int dummy_func (int a)
{
value = &a;
return 0;
} after the function returns to main?
It points to a variable that is no longer in scope, thus no longer
accessible. Any attempt to indirect through that pointer will cause
undefined behaviour. In short, the pointer points to garbage and
cannot be used until reassigned.
If this doesn't work, how could I make
it work? Do I have to allocate memory for this int and copy the original
int to that and then point value to this newly allocated int?


That could be one way, yes.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"'It can be easily shown that' means 'I saw a proof of this once (which I didn't
understand) which I can no longer remember'."
- A maths teacher
Nov 14 '05 #2
Andrej Prsa <an*********@guest.arnes.si> scribbled the following:
Hi! What happens to a globally defined pointer, e.g. void *value; that points to a particular type in a function: int dummy_func (int a)
{
value = &a;
return 0;
} after the function returns to main?
It points to a variable that is no longer in scope, thus no longer
accessible. Any attempt to indirect through that pointer will cause
undefined behaviour. In short, the pointer points to garbage and
cannot be used until reassigned.
If this doesn't work, how could I make
it work? Do I have to allocate memory for this int and copy the original
int to that and then point value to this newly allocated int?


That could be one way, yes.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"'It can be easily shown that' means 'I saw a proof of this once (which I didn't
understand) which I can no longer remember'."
- A maths teacher
Nov 14 '05 #3
Hi!
If this doesn't work, how could I make
it work? Do I have to allocate memory for this int and copy the original
int to that and then point value to this newly allocated int?


That could be one way, yes.


Is there any better way you'd suggest?

Andrej
Nov 14 '05 #4
Hi!
If this doesn't work, how could I make
it work? Do I have to allocate memory for this int and copy the original
int to that and then point value to this newly allocated int?


That could be one way, yes.


Is there any better way you'd suggest?

Andrej
Nov 14 '05 #5
Andrej Prsa <an*********@guest.arnes.si> scribbled the following:
Hi!
> If this doesn't work, how could I make
> it work? Do I have to allocate memory for this int and copy the original
> int to that and then point value to this newly allocated int?
That could be one way, yes.

Is there any better way you'd suggest?


Pass the address of a variable as a parameter to your function.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"All that flower power is no match for my glower power!"
- Montgomery Burns
Nov 14 '05 #6
Andrej Prsa <an*********@guest.arnes.si> scribbled the following:
Hi!
> If this doesn't work, how could I make
> it work? Do I have to allocate memory for this int and copy the original
> int to that and then point value to this newly allocated int?
That could be one way, yes.

Is there any better way you'd suggest?


Pass the address of a variable as a parameter to your function.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"All that flower power is no match for my glower power!"
- Montgomery Burns
Nov 14 '05 #7
Andrej Prsa <an*********@guest.arnes.si> writes:
> If this doesn't work, how could I make it work? Do I have to
> allocate memory for this int and copy the original int to that and
> then point value to this newly allocated int?


That could be one way, yes.


Is there any better way you'd suggest?


I recommend to avoid "global" (file scope) objects whenever possible.

What's the best solution to your problem depends on what your problem
is. :) If you describe a bit more elaborately what you're actually
trying to achieve, we might be able to make better suggestions.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #8
Andrej Prsa <an*********@guest.arnes.si> writes:
> If this doesn't work, how could I make it work? Do I have to
> allocate memory for this int and copy the original int to that and
> then point value to this newly allocated int?


That could be one way, yes.


Is there any better way you'd suggest?


I recommend to avoid "global" (file scope) objects whenever possible.

What's the best solution to your problem depends on what your problem
is. :) If you describe a bit more elaborately what you're actually
trying to achieve, we might be able to make better suggestions.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #9
Hi!
> If this doesn't work, how could I make it work? Do I have to
> allocate memory for this int and copy the original int to that and
> then point value to this newly allocated int?

That could be one way, yes.


Is there any better way you'd suggest?


I recommend to avoid "global" (file scope) objects whenever possible.

What's the best solution to your problem depends on what your problem
is. :) If you describe a bit more elaborately what you're actually
trying to achieve, we might be able to make better suggestions.


Sure! I'm making a script language for modeling of eclipsing binaries. I
want to be able to reach a parameter table from all kinds of plug-ins to
this language, thus I have a global table like this:

typedef struct PHOEBE_parameter_tag
{
GtkWidget *widget;
char *qualifier;
char *keyword;
char *description;
PHOEBE_type type;
void *valueptr;
} PHOEBE_parameter_tag;

PHOEBE_parameter_tag *PHOEBE_parameters;
int PHOEBE_parameters_no;

Here PHOEBE_type is a simple enumeration that defines all types that a
particular argument can be and GtkWidget is a GTK+ widget (GUI related).
PHOEBE_parameters is a global array, to which parameters are added by
calling a function:

void declare_parameter (char *qualifier, GtkWidget *parent, char *widget,
char *keyword, char *description, ...)

The variable argument list holds the type and the initial value, e.g.:

declare_parameter ("phoebe_name_value", PHOEBE, "data_star_name_entry",
"NAME", "Star name", TYPE_STRING, "New star");

As you may imagine, I want the valueptr of the global PHOEBE_parameters[i]
variable to point to whatever value corresponds to the given parameter.
Since it can be int, double, char *, but also an array of those, I hoped a
generic pointer void * would do the trick for me. And since this is a
back-end for a very large project (PHOEBE - PHysics Of Eclipsing
BinariEs), I want it to be, well, perfect! That's why I'm consulting you
guys!

Thanks for your time reading and answering!

Best wishes,

Andrej
Nov 14 '05 #10
Hi!
> If this doesn't work, how could I make it work? Do I have to
> allocate memory for this int and copy the original int to that and
> then point value to this newly allocated int?

That could be one way, yes.


Is there any better way you'd suggest?


I recommend to avoid "global" (file scope) objects whenever possible.

What's the best solution to your problem depends on what your problem
is. :) If you describe a bit more elaborately what you're actually
trying to achieve, we might be able to make better suggestions.


Sure! I'm making a script language for modeling of eclipsing binaries. I
want to be able to reach a parameter table from all kinds of plug-ins to
this language, thus I have a global table like this:

typedef struct PHOEBE_parameter_tag
{
GtkWidget *widget;
char *qualifier;
char *keyword;
char *description;
PHOEBE_type type;
void *valueptr;
} PHOEBE_parameter_tag;

PHOEBE_parameter_tag *PHOEBE_parameters;
int PHOEBE_parameters_no;

Here PHOEBE_type is a simple enumeration that defines all types that a
particular argument can be and GtkWidget is a GTK+ widget (GUI related).
PHOEBE_parameters is a global array, to which parameters are added by
calling a function:

void declare_parameter (char *qualifier, GtkWidget *parent, char *widget,
char *keyword, char *description, ...)

The variable argument list holds the type and the initial value, e.g.:

declare_parameter ("phoebe_name_value", PHOEBE, "data_star_name_entry",
"NAME", "Star name", TYPE_STRING, "New star");

As you may imagine, I want the valueptr of the global PHOEBE_parameters[i]
variable to point to whatever value corresponds to the given parameter.
Since it can be int, double, char *, but also an array of those, I hoped a
generic pointer void * would do the trick for me. And since this is a
back-end for a very large project (PHOEBE - PHysics Of Eclipsing
BinariEs), I want it to be, well, perfect! That's why I'm consulting you
guys!

Thanks for your time reading and answering!

Best wishes,

Andrej
Nov 14 '05 #11
Hi!
> If this doesn't work, how could I make
> it work? Do I have to allocate memory for this int and copy the

original> > int to that and then point value to this newly allocated
int?>
That could be one way, yes.

Is there any better way you'd suggest?


Pass the address of a variable as a parameter to your function.


Unfortunately, I cannot do that, since I don't have the actual variables
when calling this function, rather the actual constants, and e.g. &5
obviously doesn't work directly. I would lose transparency if I used int a
= 5; and then passing &a to the function, because this function is called
a zillion times with default parameter values.

Thanks,

Andrej
Nov 14 '05 #12
Hi!
> If this doesn't work, how could I make
> it work? Do I have to allocate memory for this int and copy the

original> > int to that and then point value to this newly allocated
int?>
That could be one way, yes.

Is there any better way you'd suggest?


Pass the address of a variable as a parameter to your function.


Unfortunately, I cannot do that, since I don't have the actual variables
when calling this function, rather the actual constants, and e.g. &5
obviously doesn't work directly. I would lose transparency if I used int a
= 5; and then passing &a to the function, because this function is called
a zillion times with default parameter values.

Thanks,

Andrej
Nov 14 '05 #13
Andrej Prsa wrote:
Hi! Hi Andrej,

What happens to a globally defined pointer, e.g.

void *value;

that points to a particular type in a function:

int dummy_func (int a)
{
value = &a;
return 0;
}

after the function returns to main? I agree to Joona's opinion: it's undefined.
If the pointer is evaluated before its content has been modified,
it might work. But since you cannot rely on this, don't do it.
Even worse, some compilers transfer the parameter via a register,
so that a doesn't have an address location, and the pointer
evaluation would fail.

If this doesn't work, how
could I make it work? Do I have to allocate memory for this int
and copy the original int to that and then point value to this
newly allocated int? That would work, but you mustn't forget to deallocate it afterwards,
or you'll end up with a memory leak. Your program would crash or
starve.

The better solution would be to transfer the pointer to a:

int dummy_func (int * a)
{
value = a;
return 0;
}

and then, instead of calling it with
dummy_func(toStore)
now you use dummy_func(&toStore).

If this isn't possible, because the caller doesn't know the address,
the function dummy_func wouldn't know the address, either.


Thanks for your time,

Andrej


Bernhard
Nov 14 '05 #14
Andrej Prsa wrote:
Hi! Hi Andrej,

What happens to a globally defined pointer, e.g.

void *value;

that points to a particular type in a function:

int dummy_func (int a)
{
value = &a;
return 0;
}

after the function returns to main? I agree to Joona's opinion: it's undefined.
If the pointer is evaluated before its content has been modified,
it might work. But since you cannot rely on this, don't do it.
Even worse, some compilers transfer the parameter via a register,
so that a doesn't have an address location, and the pointer
evaluation would fail.

If this doesn't work, how
could I make it work? Do I have to allocate memory for this int
and copy the original int to that and then point value to this
newly allocated int? That would work, but you mustn't forget to deallocate it afterwards,
or you'll end up with a memory leak. Your program would crash or
starve.

The better solution would be to transfer the pointer to a:

int dummy_func (int * a)
{
value = a;
return 0;
}

and then, instead of calling it with
dummy_func(toStore)
now you use dummy_func(&toStore).

If this isn't possible, because the caller doesn't know the address,
the function dummy_func wouldn't know the address, either.


Thanks for your time,

Andrej


Bernhard
Nov 14 '05 #15
Hi!
If this doesn't work, how
could I make it work? Do I have to allocate memory for this int
and copy the original int to that and then point value to this
newly allocated int?
That would work, but you mustn't forget to deallocate it afterwards,
or you'll end up with a memory leak. Your program would crash or
starve.


This particular function builds a global parameter table and once it's
complete, it isn't modified ever again. When the program is about to
finish, I free all parameter values consecutively. This brings me to
another question: I have read at numerous places that freeing memory just
before the end of the program isn't necessary, since the OS claims the
memory back when the program execution is over. Is this true?

Thanks,

Andrej
Nov 14 '05 #16
Hi!
If this doesn't work, how
could I make it work? Do I have to allocate memory for this int
and copy the original int to that and then point value to this
newly allocated int?
That would work, but you mustn't forget to deallocate it afterwards,
or you'll end up with a memory leak. Your program would crash or
starve.


This particular function builds a global parameter table and once it's
complete, it isn't modified ever again. When the program is about to
finish, I free all parameter values consecutively. This brings me to
another question: I have read at numerous places that freeing memory just
before the end of the program isn't necessary, since the OS claims the
memory back when the program execution is over. Is this true?

Thanks,

Andrej
Nov 14 '05 #17
Andrej Prsa wrote:
Hi!
> If this doesn't work, how
> could I make it work? Do I have to allocate memory for this int
> and copy the original int to that and then point value to this
> newly allocated int?

That would work, but you mustn't forget to deallocate it
afterwards, or you'll end up with a memory leak. Your program
would crash or starve.


This particular function builds a global parameter table and once
it's complete, it isn't modified ever again. When the program is
about to finish, I free all parameter values consecutively. This
brings me to another question: I have read at numerous places that
freeing memory just before the end of the program isn't necessary,
since the OS claims the memory back when the program execution is
over. Is this true?

Thanks,

Andrej


I guess you do the same thing, if you define a local variable in a
block like
{
int x;
use_of_x(x);
x = x+1;
...
}
the closing bracket removes the variable from the heap or from the
stack, wherever it has been allocated.

If you explicitely allocate memory, it's taken from heap or stack,
which has been granted to this program, and will be returned to the
OS after termination of the program.
Usually, you'll find this situation, which means that you're right.

This might be different if you use your own memory management
and allocate memory from additional resources which the compiler
isn't aware of. If you don't know how this works, you will
certainly not have to bother.

Bernhard
Nov 14 '05 #18
Andrej Prsa wrote:
Hi!
> If this doesn't work, how
> could I make it work? Do I have to allocate memory for this int
> and copy the original int to that and then point value to this
> newly allocated int?

That would work, but you mustn't forget to deallocate it
afterwards, or you'll end up with a memory leak. Your program
would crash or starve.


This particular function builds a global parameter table and once
it's complete, it isn't modified ever again. When the program is
about to finish, I free all parameter values consecutively. This
brings me to another question: I have read at numerous places that
freeing memory just before the end of the program isn't necessary,
since the OS claims the memory back when the program execution is
over. Is this true?

Thanks,

Andrej


I guess you do the same thing, if you define a local variable in a
block like
{
int x;
use_of_x(x);
x = x+1;
...
}
the closing bracket removes the variable from the heap or from the
stack, wherever it has been allocated.

If you explicitely allocate memory, it's taken from heap or stack,
which has been granted to this program, and will be returned to the
OS after termination of the program.
Usually, you'll find this situation, which means that you're right.

This might be different if you use your own memory management
and allocate memory from additional resources which the compiler
isn't aware of. If you don't know how this works, you will
certainly not have to bother.

Bernhard
Nov 14 '05 #19
Andrej Prsa wrote:
Hi!
>> > If this doesn't work, how could I make
>> > it work? Do I have to allocate memory for this int and copy
>> > the
>original> > int to that and then point value to this newly
>allocated int?>
>> That could be one way, yes.

> Is there any better way you'd suggest?


Pass the address of a variable as a parameter to your function.


Unfortunately, I cannot do that, since I don't have the actual
variables when calling this function, rather the actual constants,
and e.g. &5 obviously doesn't work directly. I would lose
transparency if I used int a = 5; and then passing &a to the
function, because this function is called a zillion times with
default parameter values.

Thanks,

Andrej


Maybe you can use a global variable which you fill with the
parameters, and then call the function without parameters.
In this case, you'd avoid the lifetime problem.

Bernhard
Nov 14 '05 #20
Andrej Prsa wrote:
Hi!
>> > If this doesn't work, how could I make
>> > it work? Do I have to allocate memory for this int and copy
>> > the
>original> > int to that and then point value to this newly
>allocated int?>
>> That could be one way, yes.

> Is there any better way you'd suggest?


Pass the address of a variable as a parameter to your function.


Unfortunately, I cannot do that, since I don't have the actual
variables when calling this function, rather the actual constants,
and e.g. &5 obviously doesn't work directly. I would lose
transparency if I used int a = 5; and then passing &a to the
function, because this function is called a zillion times with
default parameter values.

Thanks,

Andrej


Maybe you can use a global variable which you fill with the
parameters, and then call the function without parameters.
In this case, you'd avoid the lifetime problem.

Bernhard
Nov 14 '05 #21


Andrej Prsa wrote:
Hi!

If this doesn't work, how could I make
it work? Do I have to allocate memory for this int and copy the original
int to that and then point value to this newly allocated int?


That could be one way, yes.

Is there any better way you'd suggest?


Another way, perhaps not better, is the use of a static
variable.

#include <stdio.h>

void *value;

void dummy_func (int a)
{
static int buf;

buf = a;
value = &buf;
return;
}

int main(void)
{
dummy_func(21);
printf("Stored in value = %d\n",*(int *)value);
return 0;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #22


Andrej Prsa wrote:
Hi!

If this doesn't work, how could I make
it work? Do I have to allocate memory for this int and copy the original
int to that and then point value to this newly allocated int?


That could be one way, yes.

Is there any better way you'd suggest?


Another way, perhaps not better, is the use of a static
variable.

#include <stdio.h>

void *value;

void dummy_func (int a)
{
static int buf;

buf = a;
value = &buf;
return;
}

int main(void)
{
dummy_func(21);
printf("Stored in value = %d\n",*(int *)value);
return 0;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #23
In <78****************@holzmayer.ifr.rt> Bernhard Holzmayer <ho****************@deadspam.com> writes:
Andrej Prsa wrote:
Hi!

Hi Andrej,

What happens to a globally defined pointer, e.g.

void *value;

that points to a particular type in a function:

int dummy_func (int a)
{
value = &a;
return 0;
}

after the function returns to main?

I agree to Joona's opinion: it's undefined.
If the pointer is evaluated before its content has been modified,
it might work. But since you cannot rely on this, don't do it.
Even worse, some compilers transfer the parameter via a register,
so that a doesn't have an address location, and the pointer
evaluation would fail.


Nonsense! a DOES have an address inside dummy_func, regardless of how its
value was passed by the compiler and it's *always* legal to take its
address inside the function. The address becomes illegal after the
function returns. The canonical example is:

int *f(int a)
{
return &a;
}

or the similar

int *g(void)
{
int a;
return &a;
}

It is OK to call these functions *only* if their return value is
discarded.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #24
In <78****************@holzmayer.ifr.rt> Bernhard Holzmayer <ho****************@deadspam.com> writes:
Andrej Prsa wrote:
Hi!

Hi Andrej,

What happens to a globally defined pointer, e.g.

void *value;

that points to a particular type in a function:

int dummy_func (int a)
{
value = &a;
return 0;
}

after the function returns to main?

I agree to Joona's opinion: it's undefined.
If the pointer is evaluated before its content has been modified,
it might work. But since you cannot rely on this, don't do it.
Even worse, some compilers transfer the parameter via a register,
so that a doesn't have an address location, and the pointer
evaluation would fail.


Nonsense! a DOES have an address inside dummy_func, regardless of how its
value was passed by the compiler and it's *always* legal to take its
address inside the function. The address becomes illegal after the
function returns. The canonical example is:

int *f(int a)
{
return &a;
}

or the similar

int *g(void)
{
int a;
return &a;
}

It is OK to call these functions *only* if their return value is
discarded.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #25
Andrej Prsa <an*********@guest.arnes.si> writes:
>> > If this doesn't work, how could I make it work? Do I have to
>> > allocate memory for this int and copy the original int to that and
>> > then point value to this newly allocated int?
>>
>> That could be one way, yes.
>
> Is there any better way you'd suggest?


I recommend to avoid "global" (file scope) objects whenever possible.

What's the best solution to your problem depends on what your problem
is. :) If you describe a bit more elaborately what you're actually
trying to achieve, we might be able to make better suggestions.


Sure! I'm making a script language for modeling of eclipsing binaries. I
want to be able to reach a parameter table from all kinds of plug-ins to
this language, thus I have a global table like this:

typedef struct PHOEBE_parameter_tag
{
GtkWidget *widget;
char *qualifier;
char *keyword;
char *description;
PHOEBE_type type;
void *valueptr;
} PHOEBE_parameter_tag;

PHOEBE_parameter_tag *PHOEBE_parameters;
int PHOEBE_parameters_no;

Here PHOEBE_type is a simple enumeration that defines all types that a
particular argument can be and GtkWidget is a GTK+ widget (GUI related).
PHOEBE_parameters is a global array, to which parameters are added by
calling a function:

void declare_parameter (char *qualifier, GtkWidget *parent, char *widget,
char *keyword, char *description, ...)

The variable argument list holds the type and the initial value, e.g.:

declare_parameter ("phoebe_name_value", PHOEBE, "data_star_name_entry",
"NAME", "Star name", TYPE_STRING, "New star");

As you may imagine, I want the valueptr of the global PHOEBE_parameters[i]
variable to point to whatever value corresponds to the given parameter.
Since it can be int, double, char *, but also an array of those, I hoped a
generic pointer void * would do the trick for me.


You could allocate memory (e.g. using `malloc') and point `valueptr' to
it. However, this seems a bit wasteful when you only want to store a
single `int' or `double' object. Maybe you could use a union?

typedef struct PHOEBE_parameter_tag {
/* ... */
PHOEBE_type type;
union {
int i;
double d;
char *str;
int *i_array;
double *d_array;
} value;
};

In your `declare_parameter' function, you could then allocate memory for
strings or arrays, but avoid doing so for `int' or `double' objects:

switch (type)
{
case TYPE_INT:
PHOEBE_parameters [i].value.i = va_arg (ap, int);
break;

case TYPE_DOUBLE:
PHOEBE_parameters [i].value.d = va_arg (ap, double);
break;

case TYPE_STRING:
{
const char *const str = va_arg (ap, const char *);

PHOEBE_parameters [i].value.str = malloc (strlen (str) + 1);
if (PHOEBE_parameters [i].value.str != NULL)
strcpy (PHOEBE_parameters [i].value.str, str);
else
{
/* Handle memory allocation failure. */
}
break;
}

/* ... */
}

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #26
Andrej Prsa <an*********@guest.arnes.si> writes:
>> > If this doesn't work, how could I make it work? Do I have to
>> > allocate memory for this int and copy the original int to that and
>> > then point value to this newly allocated int?
>>
>> That could be one way, yes.
>
> Is there any better way you'd suggest?


I recommend to avoid "global" (file scope) objects whenever possible.

What's the best solution to your problem depends on what your problem
is. :) If you describe a bit more elaborately what you're actually
trying to achieve, we might be able to make better suggestions.


Sure! I'm making a script language for modeling of eclipsing binaries. I
want to be able to reach a parameter table from all kinds of plug-ins to
this language, thus I have a global table like this:

typedef struct PHOEBE_parameter_tag
{
GtkWidget *widget;
char *qualifier;
char *keyword;
char *description;
PHOEBE_type type;
void *valueptr;
} PHOEBE_parameter_tag;

PHOEBE_parameter_tag *PHOEBE_parameters;
int PHOEBE_parameters_no;

Here PHOEBE_type is a simple enumeration that defines all types that a
particular argument can be and GtkWidget is a GTK+ widget (GUI related).
PHOEBE_parameters is a global array, to which parameters are added by
calling a function:

void declare_parameter (char *qualifier, GtkWidget *parent, char *widget,
char *keyword, char *description, ...)

The variable argument list holds the type and the initial value, e.g.:

declare_parameter ("phoebe_name_value", PHOEBE, "data_star_name_entry",
"NAME", "Star name", TYPE_STRING, "New star");

As you may imagine, I want the valueptr of the global PHOEBE_parameters[i]
variable to point to whatever value corresponds to the given parameter.
Since it can be int, double, char *, but also an array of those, I hoped a
generic pointer void * would do the trick for me.


You could allocate memory (e.g. using `malloc') and point `valueptr' to
it. However, this seems a bit wasteful when you only want to store a
single `int' or `double' object. Maybe you could use a union?

typedef struct PHOEBE_parameter_tag {
/* ... */
PHOEBE_type type;
union {
int i;
double d;
char *str;
int *i_array;
double *d_array;
} value;
};

In your `declare_parameter' function, you could then allocate memory for
strings or arrays, but avoid doing so for `int' or `double' objects:

switch (type)
{
case TYPE_INT:
PHOEBE_parameters [i].value.i = va_arg (ap, int);
break;

case TYPE_DOUBLE:
PHOEBE_parameters [i].value.d = va_arg (ap, double);
break;

case TYPE_STRING:
{
const char *const str = va_arg (ap, const char *);

PHOEBE_parameters [i].value.str = malloc (strlen (str) + 1);
if (PHOEBE_parameters [i].value.str != NULL)
strcpy (PHOEBE_parameters [i].value.str, str);
else
{
/* Handle memory allocation failure. */
}
break;
}

/* ... */
}

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #27
Andrej Prsa <an*********@guest.arnes.si> writes:
This brings me to another question: I have read at numerous places
that freeing memory just before the end of the program isn't
necessary, since the OS claims the memory back when the program
execution is over. Is this true?


That depends on the OS. All modern desktop or server systems reclaim
the memory automatically, but that's not necessarily the case for
embedded devices.

If you search the archives of this newsgroup on what's considered better
style, you'll find there's no consensus. I personally usually don't
bother to free memory immediately before the program terminates, because
I'm very sure that the kind of programs I write will never be ported to
embedded devices. :)

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #28
Andrej Prsa <an*********@guest.arnes.si> writes:
This brings me to another question: I have read at numerous places
that freeing memory just before the end of the program isn't
necessary, since the OS claims the memory back when the program
execution is over. Is this true?


That depends on the OS. All modern desktop or server systems reclaim
the memory automatically, but that's not necessarily the case for
embedded devices.

If you search the archives of this newsgroup on what's considered better
style, you'll find there's no consensus. I personally usually don't
bother to free memory immediately before the program terminates, because
I'm very sure that the kind of programs I write will never be ported to
embedded devices. :)

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #29
Hi, Martin!
You could allocate memory (e.g. using `malloc') and point `valueptr' to
it. However, this seems a bit wasteful when you only want to store a
single `int' or `double' object. Maybe you could use a union?


:) This really makes me smile, because I had exactly these two options in
mind. I used mallocs for everything and void * to point to the space, but
after your reply I decided to go and change it to union. So now I am using
the code you suggested. Thank you very much!

Best wishes,

Andrej
Nov 14 '05 #30
Hi, Martin!
You could allocate memory (e.g. using `malloc') and point `valueptr' to
it. However, this seems a bit wasteful when you only want to store a
single `int' or `double' object. Maybe you could use a union?


:) This really makes me smile, because I had exactly these two options in
mind. I used mallocs for everything and void * to point to the space, but
after your reply I decided to go and change it to union. So now I am using
the code you suggested. Thank you very much!

Best wishes,

Andrej
Nov 14 '05 #31
Martin Dickopp wrote:
.... snip ...
If you search the archives of this newsgroup on what's considered
better style, you'll find there's no consensus. I personally
usually don't bother to free memory immediately before the
program terminates, because I'm very sure that the kind of
programs I write will never be ported to embedded devices. :)


In fact on some systems doing such frees can significantly slow
down program exit when there are a significant number of items to
be freed. Horrible examples include lcc-win32 and VC6, because
both depend on Microsoft libraries for the free operation. With
these systems it is not hard to generate an exit delay measured in
minutes.

--
Some useful references:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://www.eskimo.com/~scs/C-faq/top.html>
<http://benpfaff.org/writings/clc/off-topic.html>
Nov 14 '05 #32

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: David Hitillambeau | last post by:
Hi guys, As I am new to Python, i was wondering how to declare and use global variables. Suppose i have the following structure in the same module (same file): def foo: <instructions>...
16
by: Andrej Prsa | last post by:
Hi! What happens to a globally defined pointer, e.g. void *value; that points to a particular type in a function: int dummy_func (int a) {
204
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
8
by: Rob T | last post by:
When I was using VS2003, I was able to compile my asp.net project locally on my machine and copy it to the production server and it would run just fine. I've now converted to VS2005. The project...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.