Pointeur void *

Fermé
do'urden Messages postés 15 Date d'inscription jeudi 10 novembre 2005 Statut Membre Dernière intervention 15 juin 2008 - 4 mai 2006 à 09:26
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 - 5 mai 2006 à 21:31
Bonjour,

voilà mon problème : je souhaiterais pouvoir entrer les données référencées par un pointeur de type short *** dans un pointeur de type void *.

Avant de débuter le "transfert" des données, je sauvegarde dans un autre pointeur void * l'adresse de début de mon pointeur. Mais je ne suis pas sûr que ma façon de faire soit correcte.

Mais mon principal souci se situe surtout au niveau du "transfert" des données entre les deux pointeurs : en effet, je ne suis pas sûr qu'au bout du compte, le pointeur void * référence bien un tableau contenant les données du pointeur short ***.

Comme ce que je raconte n'est peut-être pas très clair (je m'embrouille un peu ;-), voilà mon code :
dataToSave->data = malloc(dataToSave->nvox * dataToSave->nbyper);

    debutData = dataToSave->data;

    for(i=0; i<image->width; i++){
        for(j=0; j<image->height;j++){
            for(k=0; k<image->depth; k++){
                dataToSave->data = &(image->mri[i][j][k]);
                dataToSave->data++;
            }
        }
    }
    
    dataToSave->data = debutData;

Ici, data est le fameux pointeur de type void * et mri celui de type short ***.

L'allocation de data donne un tableau de taille égale au nombre de données contenues dans mri[width][height][depth], nvox étant width*height*depth et nbyper le nombre de bytes pour une donnée.

Je suis par-contre dans l'obligation d'allouer data à cette taille, étant donné qu'il est défini dans une bibliothèque que je n'ai pas programmée.


J'ai essayé un autre moyen qui me paraissait plus juste, mais cela engendrait des erreurs :
dataToSave->data = (short *)malloc(dataToSave->nvox * dataToSave->nbyper);

    debutData = dataToSave->data;

    for(i=0; i<image->width; i++){
        for(j=0; j<image->height;j++){
            for(k=0; k<image->depth; k++){
                (*dataToSave->data) = image->mri[i][j][k];
                dataToSave->data++;
            }
        }
    }

    dataToSave->data = debutData;

Cela produit une erreur qui me dit :
file_nifti.c:607: warning: dereferencing `void *' pointer
file_nifti.c:607: void value not ignored as it ought to be

La ligne 607 étant celle où se fait l'affectation.

Je me retrouve donc complètement bloqué là-dessus. Si qqn sait ce qu'il faut faire, je le remercie d'avance ;-)

2 réponses

kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
4 mai 2006 à 14:19
Salut,

Je repars sur ton premier code.
Assure toi d'abord pour l'allocation que dataToSave->nbyper ait la taille de sizeof( void).
Sous gcc il me semble qu'un void a la même taille qu'un int =>4 octets, donc assez pour accueillir une adresse.

Le problème suivant c'est ça:
dataToSave->data = &(image->mri[i][j][k]);


&(image->mri[i][j][k]) c'est l'adresse d'un short.
dataToSave->data c'est l'adresse d'un emplacement dans un tableau void.
Là tu modifies l'adresse de cet emplacement, le résultat doit être un peu bizzare....
Je pense que tu veux plutôt mettre la valeur de ton short à cet emplacement (tu gâche de l'espace: un short=2 octets, et un void=4 octets sous gcc):
*dataToSave->data = image->mri[i][j][k];


Ou bien mettre l'adresse de ce short à cet emplacement (du coup l'emplacement dans ce tableau void sera un pointeur):
*dataToSave->data = &(image->mri[i][j][k]);


Je ne sais pas ce que tu veux faire, mais tu consommes inutilement de la memoire. Si tu passes la valeur du short: tu stocke sur 4 octets une valeur qui aurait pu être stockée sur 2. Et si tu passes l'adresse de tes shorts dans ton tableau, là il te faut 4 octets (tandis que deux auraient suffis si tu avais passés la valeur).
1
do'urden Messages postés 15 Date d'inscription jeudi 10 novembre 2005 Statut Membre Dernière intervention 15 juin 2008 1
5 mai 2006 à 09:25
Salut et merci pour ta réponse,

j'ai finalement trouvé la solution à mon problème en faisant :
(*(short *)dataToSave->data) =image->mri[i][j][k];
dataToSave->data += dataToSave->nbyper;


Pour ce qui est de gâcher l'espace mémoire, j'en suis conscient mais je ne peux malheureusement pas faire autrement, les types de données référencées par les deux pointeurs étant imposés.

Mais si, malgré ça, il y a un moyen pour éviter ça, je suis prenneur ;-)
1
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
5 mai 2006 à 21:31
Voui y'en a un :-)
Tu as un pointeur void qui pointe sur un grand espace.
Il te suffit de prendre un pointeur short et de le faire pointer sur cet espace, ce qui le'ordonnera en espaces scindés par la taille de shorts.
Par exemple:
short *dataToSave_short;
dataToSave->data = malloc(dataToSave->nvox * dataToSave->nbyper);
dataToSave_short=(short *)dataToSave->data;

Pour le coup il faut bien examiner l'espace que tu prends avec l'allocation pour ton void (voir si tu n'en prend pas trop).
0