OVH Cloud OVH Cloud

Comment mettre des valeurs dans un tableau de void ?

17 réponses
Avatar
Jseb
Bonjour,

Je voudrais stocker les adresses mémoires retournées par malloc dans
un tableau de void.
Mais comme "void" est un type sans taille,

void *tvoid;
int i=0;
tvoid[i]=malloc(bidule);
i++;

ne fonctionne pas.
Peut on déclarer un tableau de void, ou, pour être plus exact, peut on
accéder par index à un pointeur void ?

Merci.

--
Alussinan, l'internette que ça fout la trouille.

10 réponses

1 2
Avatar
DINH Viêt Hoà

Je voudrais stocker les adresses mémoires retournées par malloc dans
un tableau de void.
Mais comme "void" est un type sans taille,

void *tvoid;
int i=0;
tvoid[i]=malloc(bidule);
i++;

ne fonctionne pas.
Peut on déclarer un tableau de void


je ne crois pas, mais à vérifier ...
enfin j'aimerai bien savoir la taille qu'il ferait.
D'ailleurs, peut-on déclarer une donnée void ?

ou, pour être plus exact, peut on
accéder par index à un pointeur void ?


ce que tu peux faire pour remplir ton tableau, c'est le
caster de (void *) en (char *) et travailler dessus.

--
DINH V. Hoa,

<< mon chef est venu me chercher à la machine à café l'autre jour:
"je savais bien que je vous trouverais ici" >> -- s.

Avatar
Yves ROMAN

Bonjour,

Je voudrais stocker les adresses mémoires retournées par malloc dans
un tableau de void.


Tu dois les stocker dans des void * car ce sont des adresses.

Mais comme "void" est un type sans taille,



Alors que void * a une taille

void *tvoid;
int i=0;
tvoid[i]=malloc(bidule);
i++;

ne fonctionne pas.
Peut on déclarer un tableau de void, ou, pour être plus exact, peut on
accéder par index à un pointeur void ?



#define N 2
void *tvoid[N] ;
int i ;
for ( i=0 ; i<N i++ )
{
tvoid[i} = malloc(bidule) ;
}

Merci.



Avatar
Bruno Desthuilliers
Jseb wrote:
Bonjour,


Bonjour

NB : ça fait un bout de temps que je n'ai pas fait de C, j'espère que je
ne vais pas dire trop de conneries... Merci aux gourous de service de
corriger si nécessaire.

Je voudrais stocker les adresses mémoires retournées par malloc dans
un tableau de void.
Mais comme "void" est un type sans taille,


<pour les gourous : void est-il un type ?>

Quoi qu'il en soit, un void*, lui, a une taille.

#include <stdio.h>

int main(void)
{
void *vptr = NULL;
printf("taille d'un void* sur ma machine : %dn", sizeof(vptr));
return 0;
}

[ dev]$ gcc -o alu3 -Wall -ansi -pedantic alu3.c
[ dev]$ ./alu3
taille d'un void* sur ma machine : 4


void *tvoid;
int i=0;
tvoid[i]=malloc(bidule);
i++;

ne fonctionne pas.


En effet :

[ dev]$ gcc -o aluerr -Wall -ansi -pedantic aluerr.c
aluerr.c:3: warning: type defaults to `int' in declaration of `tvoid'
aluerr.c:3: warning: ISO C89 forbids variable-size array `tvoid'
aluerr.c:3: variable-size type declared outside of any function
aluerr.c:3: variable-sized object may not be initialized
aluerr.c:3: conflicting types for `tvoid'
aluerr.c:1: previous declaration of `tvoid'
aluerr.c:3: warning: implicit declaration of function `malloc'
aluerr.c:3: `bidule' undeclared here (not in a function)
aluerr.c:3: ISO C forbids data definition with no type or storage class
aluerr.c:4: parse error before '++' token


Peut on déclarer un tableau de void,


Non, mais un tableau de pointeurs void, oui.

void *vtab[10];

ou, pour être plus exact, peut on
accéder par index à un pointeur void ?


Si ta question est 'peut-on utiliser l'arithmétique des pointeurs sur un
void *", la réponse est non :

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

#define SIZE 10

int main(void)
{
int i;
void *vptr = malloc(sizeof(int) * SIZE);
if (vptr == NULL)
{
fprintf(stderr
, "Malloc failed, file %s line %dn"
, __FILE__
, __LINE__
);
return EXIT_FAILURE;
}

for (i = 0; i < SIZE; i++)
{
printf("L'adresse stockee dans vptr[%d] est %pn", i, vptr[i]);
}

free(vptr);
return EXIT_SUCCESS;
}

[ dev]$ gcc -o alu4 -Wall -ansi -pedantic alu4.c
alu4.c: In function `main':
alu4.c:18: warning: pointer of type `void *' used in arithmetic
alu4.c:18: warning: dereferencing `void *' pointer
alu4.c:18: invalid use of void expression

Je te laisse regarder pourquoi dans ton livre de C.

Maintenant, ce que tu veux c'est stocker des adresses retournées par
malloc(). Donc des void*. Tu veux les stocker dans un tableau dynamique
(appelons ça comme ça) de pointeurs void. Ce n'est donc pas un pointeur
void qu'il te faut, mais un pointeur sur pointeur void.

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

#define SIZE 10
int main(void)
{
void **vtab;
int i;

vtab = malloc(sizeof (*vtab) * SIZE);
if (vtab == NULL)
{
fprintf(stderr
, "Malloc failed, file %s line %dn"
, __FILE__
, __LINE__
);
return EXIT_FAILURE;
}

for (i = 0; i < SIZE; i++)
{
vtab[i] = malloc(SIZE);
if (vtab[i] == NULL)
{
fprintf(stderr
, "Malloc failed, file %s line %dn"
, __FILE__
, __LINE__
);
/* sortie sauvage, il faudrait nettoyer avant */
return EXIT_FAILURE;
}
}

for(i = 0; i < SIZE; i++)
{
printf("L'adresse stockee dans vtab[%d] est %pn", i, vtab[i]);
free(vtab[i]);
vtab[i] = NULL;
}

free(vtab);

return EXIT_SUCCESS;
}

[ dev]$ gcc -Wall -ansi -pedantic -o alu2 alussinan2.c
[ dev]$ ./alu2
L'adresse stockee dans vtab[0] est 0x8049840
L'adresse stockee dans vtab[1] est 0x8049850
L'adresse stockee dans vtab[2] est 0x8049860
L'adresse stockee dans vtab[3] est 0x8049870
L'adresse stockee dans vtab[4] est 0x8049880
L'adresse stockee dans vtab[5] est 0x8049890
L'adresse stockee dans vtab[6] est 0x80498a0
L'adresse stockee dans vtab[7] est 0x80498b0
L'adresse stockee dans vtab[8] est 0x80498c0
L'adresse stockee dans vtab[9] est 0x80498d0

HTH
Bruno

--
Soyez Zen :
http://www.laotseu.net

Avatar
Patrick \Zener\ BRUNET
Salut.

"Jseb" a écrit dans le message news:

Bonjour,

Je voudrais stocker les adresses mémoires retournées par malloc dans
un tableau de void.
Mais comme "void" est un type sans taille,


Plus précisément, void est un non-type, c'est à dire qu'un pointeur void *
pointe vers un espace mémoire non typé et non découpé.
malloc() retourne un pointeur void * précisément pour ça : l'adresse
retournée est :
- correctement alignée pour n'importe quel type,
- celle d'un espace au moins aussi grand (en octets) que ce qui a été
demandé.

Avant d'utiliser un tel pointeur, il faut commencer par le typer
convenablement. En effet :


void *tvoid;


sizeof( void)
et
tvoid[i]

sont des expressions dépourvues de sens (du moins sémantiquement ; si le
compilo les accepte alors il est pas terrible).

Donc typiquement, si T est un type,

#define N 666
T * pT;
int i;

pT = (T *) malloc( N * sizeof( T));
if( pT != NULL)
{
for( i = 0; i < N; i++)
pT[i] = <une valeur typée T>;
}


et rien n'empêche T d'être le type "void *" (j'ai pas dit "void").
et rien n'empêche le tableau d'être statique :

void * aT[N];

Dans ce cas évidemment, le if n'a aucun intérêt.

aT est typé "void * *", et donc aT[i] est typé "void *" et peut recevoir un
pointeur.

Clair ?

PZB

Avatar
Jseb
Merci pour toutes les réponses.

En résumé, l'astuce consiste à déclarer un tableau de pointeurs void,
qui eux ont une taille. Je le déclare ainsi: void *result[N]; et je
l'utilise comme suit: result[i]

Pour pouvoir fixer dynamiquement la taille de mon tableau, je pourrais
utiliser un pointeur de pointeurs void (void **result), que je
pourrais également adresser ainsi: &result[i] (après avoir alloué de
la mémoire pour result)


malloc() retourne un pointeur void * précisément pour ça : l'adresse
retournée est :
- correctement alignée pour n'importe quel type,


Ca par contre, je comprend pas. L'adresse est de toute façon unique,
que l'on adresse ensuite des octets, des words , des quad...
Ca va être une adresse de la taille du bus, c'est tout, non?
C'est pour ça que j'ai jamais compris pourquoi on récupèrait un type
void, et qu'il ne fallait pas caster le retour de malloc.


Clair ?


Je pense que j'ai compris, après quelques gratouillis de mon cuir
chevelu.


--
Alussinan, l'internette que ça fout la trouille.

Avatar
Gabriel Dos Reis
Jseb writes:

| >malloc() retourne un pointeur void * précisément pour ça : l'adresse
| >retournée est :
| >- correctement alignée pour n'importe quel type,
|
| Ca par contre, je comprend pas. L'adresse est de toute façon unique,
| que l'on adresse ensuite des octets, des words , des quad...
| Ca va être une adresse de la taille du bus, c'est tout, non?

de la RATP ?

-- Gaby
Avatar
DINH Viêt Hoà

Je voudrais stocker les adresses mémoires retournées par malloc dans
un tableau de void.
Mais comme "void" est un type sans taille,

void *tvoid;
int i=0;
tvoid[i]=malloc(bidule);
i++;

ne fonctionne pas.
Peut on déclarer un tableau de void


je ne crois pas, mais à vérifier ...
enfin j'aimerai bien savoir la taille qu'il ferait.
D'ailleurs, peut-on déclarer une donnée void ?

--
DINH V. Hoa,

<< mon chef est venu me chercher à la machine à café l'autre jour:
"je savais bien que je vous trouverais ici" >> -- s.

Avatar
Vincent Lefevre
Dans l'article ,
DINH Viêt Hoà écrit:

Peut on déclarer un tableau de void


je ne crois pas, mais à vérifier ...


Tout à fait, puisque ce n'est pas un type d'objet (car c'est un type
incomplet). Cf 6.2.5.

enfin j'aimerai bien savoir la taille qu'il ferait.


C'est bien là la notion de type incomplet: on ne peut pas déterminer
la taille.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/> - 100%
validated (X)HTML - Acorn Risc PC, Yellow Pig 17, Championnat International
des Jeux Mathématiques et Logiques, TETRHEX, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA


Avatar
Yves ROMAN

Merci pour toutes les réponses.

En résumé, l'astuce consiste à déclarer un tableau de pointeurs void,
qui eux ont une taille. Je le déclare ainsi: void *result[N]; et je
l'utilise comme suit: result[i]

Pour pouvoir fixer dynamiquement la taille de mon tableau, je pourrais
utiliser un pointeur de pointeurs void (void **result), que je
pourrais également adresser ainsi: &result[i] (après avoir alloué de
la mémoire pour result)



Tu l'adresses aussi par result[i] (qui donne un void *)
&result[i] == result+i == adresse du pointeur d'indice i, et non son contenu

malloc() retourne un pointeur void * précisément pour ça : l'adresse
retournée est :
- correctement alignée pour n'importe quel type,


Ca par contre, je comprend pas. L'adresse est de toute façon unique,
que l'on adresse ensuite des octets, des words , des quad...
Ca va être une adresse de la taille du bus, c'est tout, non?


Sur certaines machines, on peut avoir des problèmes si on accède à un entier via
une adresse non correctement alignée (pas multiple de 4 par exemple sur
adressage 32bits)
C'ets pour éviter ca que malloc() renvoit une adresse alignée, ou que le
compilateur rajoute du padding dans les structures.

C'est pour ça que j'ai jamais compris pourquoi on récupèrait un type
void, et qu'il ne fallait pas caster le retour de malloc.

Ca n'a rien a voir : voir la FAQ à ce sujet


On reçoit un void * compatible avec n'importe qu'elle pointeur en C. On
conseille de ne pas caster pour s'assurer qu'on n'a pas oublié d'inclure le
prototype de malloc() et donc que le compilateur sait que cette fonction
retourne une adresse et non un entier.
En effet si on a oublié le prototype, malloc() est supposée retourner un int,
qu'on ne peut pas mettre dans un pointeur.
Si on rajoute le cast en oubliant le prototype, le compilateur fera la
conversion int vers pointeur sur le resultat de malloc(), sans rien dire, ce qui
peut donner des choses curieuses, par exemple si int et pointeur n'ont pas la
même taille.

Ce sujet est un constant générateur de trolls à cause de ceci :
En C++, il est nécessaire de caster le retour de malloc(). Le deuxième camp
préfère mettre le cast pour obtenir du code compatible C et C++ estimant le
risque dû au protoype manquant négligeable devant l'avantage.
De plus, à l'époque ou void n'existait pas en C, malloc() renvoyait un char *.
Il était donc nécessaire de caster son retour pour le mettre dans autre choqe
qu'un char *. Donc une bonne partie d'ancien code contient ce cast.

J'espère avoir fait une bonne synthèse du problème.


Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Jseb wrote:

Je voudrais stocker les adresses mémoires retournées par malloc dans
un tableau de void.


Impossible. Pour stocker une adresse, il faut un pointeur. Tu veux
probablement un tableau de void*.

Repense à ton problème sur ces bases, ça devrait aller mieux. (Et cesse de
confondre tableau et pointeur, merci).

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

1 2