PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.c > Storing integer values in a void*
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Storing integer values in a void*

Réponse
 
LinkBack Outils de la discussion
Vieux 11/04/2008, 12h12   #1
lithiumcat@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Storing integer values in a void*

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
  Réponse avec citation
Vieux 11/04/2008, 13h39   #2
Sebastian Morawietz
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Storing integer values in a void*

Hi there,

how about using a union and a type variable, instead of just a
pointer?

Hope this s

Seb

-------------------

#include <stdio.h>
#include <stdlib.h>


#define VALUE_TYPE_POINTER (1)
#define VALUE_TYPE_FLOAT (2)
#define VALUE_TYPE_INT (3)

typedef int value_type_t;

typedef struct node_t
{
value_type_t type;
union {
int intValue;
float floatValue;
void* pointerValue;
} value;
} node_t;

node_t*
node_new_with_pointer( void* value )
{
node_t* result = calloc( 1, sizeof( node_t ) );

result->type = VALUE_TYPE_POINTER;
result->value.pointerValue=value;

return result;
}

node_t*
node_new_with_int( int value )
{
node_t* result = calloc( 1, sizeof( node_t ) );

result->type = VALUE_TYPE_INT;
result->value.intValue=value;

return result;
}

int
main()
{
node_t* node = node_new_with_int( 17 );

printf( "node is an int type: %s\nValue: %i\n",
node->type == VALUE_TYPE_INT ? "true" : "false",
node->value.intValue );
free(node );

char* test="blahblah";
node=node_new_with_pointer( test );

printf( "node is a pointer-type: %s\n"
"Pointer is equal to test: %s\n",
node->type == VALUE_TYPE_POINTER ? "true" : "false",
test == node->value.pointerValue ? "true" : "false" );

free( node );

return 0;
}


  Réponse avec citation
Vieux 11/04/2008, 15h59   #3
Ben Bacarisse
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Storing integer values in a void*

lithiumcat@gmail.com writes:

> I'm using some functions to store and retrieve data as a void*.

<snip>
> 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)

<snip cast void * to int method>
> However I'm not sure any standard guarantees this to work,


No, you are right. It is not guaranteed to work. It will work in
lots of cases, but it is not portable.

> 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 ?


Clever but, no, not portable. Even constructing an address outside of
and object (except for the off-by-one-at-the-end permission) is
undefined.

The only portable solution that I can think of is the union idea
already posted. This, of course, requires changes to the AVL tree
code, so it may not be an option.

--
Ben.
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 17h34.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,12721 seconds with 11 queries