L
lithiumcat
Hello,
I'm using some functions to store and retrieve data as a void*. They
happen to be an AVL-tree implementation, but that's irrelevant for my
question, so let's just think of a black box that handles void*.
I think there is no problem as long as I use pointers to data
allocated elsewhere, because the standard says that a pointer to
whatever, converted to a void*, and converted back to the same
whatever, gives the same pointer.
But I want to use that code to store small integers (maybe not more
than a thousand, but I don't want to hardcode a limit), and I'm
wondering whtat is the best portable way to do it.
I guess the most natural way to use these functions would be to malloc
space for a single int, and use the returned pointer as a void* (with
implicit conversion when calling the storing function). Something like
that :
/* storage */
int *i = malloc(sizeof *i);
*i = value_to_be_stored;
store_data_as_void_ptr(i);
/* retrieval */
int *i = get_data_returned_as_void_ptr();
/* use *i */
However this does not look very efficient in terms of memory, because
of the malloc() overhead for every integer, plus the memory used for
the void* in the blackbox.
I thought that because void* is basically a pointer, and therefore a
numeric value, it might be possible to store the value directly into
the pointer value. I guess something like the following would work on
some architectures :
/* storage */
int i = value_to_be_stored;
void *data = (void *)i;
store_data_as_void_ptr(data);
/* retrieval */
int i;
void *data = get_data_returned_as_void_ptr();
i = (int)data;
/* use i */
However I'm not sure any standard guarantees this to work, so I was
looking for a more portable solution. I thought doing some pointer
arithmetics :
/* global variable to be used for base of pointers */
char base;
/* storage */
int i = value_to_be_stored;
char *data = &base + i;
store_data_as_voir_ptr(data);
/* retrieval */
int i;
char *data = get_data_returned_as_void_ptr();
i = data - &base;
/* use i */
But is this really portable (assuming i is small enough so there is no
overflow) ? I guess the pointers will probably be invalid, but as they
are never dereferenced, it is alright, isn't it ?
Have I made a mistake in all this ? Is there a better way to handle my
problem ?
Thanks in advanced for your ideas.
Natacha
I'm using some functions to store and retrieve data as a void*. They
happen to be an AVL-tree implementation, but that's irrelevant for my
question, so let's just think of a black box that handles void*.
I think there is no problem as long as I use pointers to data
allocated elsewhere, because the standard says that a pointer to
whatever, converted to a void*, and converted back to the same
whatever, gives the same pointer.
But I want to use that code to store small integers (maybe not more
than a thousand, but I don't want to hardcode a limit), and I'm
wondering whtat is the best portable way to do it.
I guess the most natural way to use these functions would be to malloc
space for a single int, and use the returned pointer as a void* (with
implicit conversion when calling the storing function). Something like
that :
/* storage */
int *i = malloc(sizeof *i);
*i = value_to_be_stored;
store_data_as_void_ptr(i);
/* retrieval */
int *i = get_data_returned_as_void_ptr();
/* use *i */
However this does not look very efficient in terms of memory, because
of the malloc() overhead for every integer, plus the memory used for
the void* in the blackbox.
I thought that because void* is basically a pointer, and therefore a
numeric value, it might be possible to store the value directly into
the pointer value. I guess something like the following would work on
some architectures :
/* storage */
int i = value_to_be_stored;
void *data = (void *)i;
store_data_as_void_ptr(data);
/* retrieval */
int i;
void *data = get_data_returned_as_void_ptr();
i = (int)data;
/* use i */
However I'm not sure any standard guarantees this to work, so I was
looking for a more portable solution. I thought doing some pointer
arithmetics :
/* global variable to be used for base of pointers */
char base;
/* storage */
int i = value_to_be_stored;
char *data = &base + i;
store_data_as_voir_ptr(data);
/* retrieval */
int i;
char *data = get_data_returned_as_void_ptr();
i = data - &base;
/* use i */
But is this really portable (assuming i is small enough so there is no
overflow) ? I guess the pointers will probably be invalid, but as they
are never dereferenced, it is alright, isn't it ?
Have I made a mistake in all this ? Is there a better way to handle my
problem ?
Thanks in advanced for your ideas.
Natacha