OVH Cloud OVH Cloud

casting short* [4] en short[4][64] ?

31 réponses
Avatar
Bernie
Bonjour,
J'ai déjà rencontré ce prb et je l'avais solutionné de manière "batarde",
mais à force je me dis qu'il faudrait que je découvre un peu le fond du
prb....

soit une variable short* toto[4], qqsoit i toto[i] = (short*)malloc(64);
soit une fonction f déclarée par : void f(short param[4][64]);

comment caster "proprement" la variable toto pour la passer à f ?

merci d'avance ...

10 réponses

1 2 3 4
Avatar
Pierre Maurette
Bonjour,
J'ai déjà rencontré ce prb et je l'avais solutionné de manière "batarde",
mais à force je me dis qu'il faudrait que je découvre un peu le fond du
prb....

soit une variable short* toto[4], qqsoit i toto[i] = (short*)malloc(64);
soit une fonction f déclarée par : void f(short param[4][64]);
Ce ne serait pas:

toto[i] = (short*)malloc(64 * sizeof(short));

Ce qui ne résoud pas le cast (ni le fait que c'est du C ;-))
--
Pierre

Avatar
Bernie
"Pierre Maurette" a écrit dans le message de
news:424038d3$0$1558$
Bonjour,
J'ai déjà rencontré ce prb et je l'avais solutionné de manière
"batarde",


mais à force je me dis qu'il faudrait que je découvre un peu le fond du
prb....

soit une variable short* toto[4], qqsoit i toto[i] = (short*)malloc(64);
soit une fonction f déclarée par : void f(short param[4][64]);
Ce ne serait pas:

toto[i] = (short*)malloc(64 * sizeof(short));

Ce qui ne résoud pas le cast (ni le fait que c'est du C ;-))
--
Pierre


ben effectivement :
* Je me suis trompé en tapant mon allocation, mais dans mes codes c'est ok
j'explicite toujours le type via sizeof, meme pour des char ou unsigned
char...je trouve que c'est + lisible...
* C'est bien du C, mais a force de mélanger allègrement les 2, j'avoue que
je ne distingue + la frontière...

Par contre le prb reste ouvert, et sous une forme + générale,
est-il possible de passer une var déclarée TYPE* toto[4] à une fonction qui
explicite que son param est TYPE param[4]64] ?


Avatar
Pierre Maurette
[...]
ben effectivement :
* Je me suis trompé en tapant mon allocation, mais dans mes codes c'est ok
j'explicite toujours le type via sizeof, meme pour des char ou unsigned
char...je trouve que c'est + lisible...
* C'est bien du C, mais a force de mélanger allègrement les 2, j'avoue que
je ne distingue + la frontière...
Chutt ..


Par contre le prb reste ouvert, et sous une forme + générale,
est-il possible de passer une var déclarée TYPE* toto[4] à une fonction qui
explicite que son param est TYPE param[4]64] ?
Passser (short( *)[64])toto ?

(j'ai triché ;-))
--
Pierre

Avatar
Marc Boyer
Bernie wrote:
Par contre le prb reste ouvert, et sous une forme + générale,
est-il possible de passer une var déclarée TYPE* toto[4] à une fonction qui
explicite que son param est TYPE param[4]64] ?


Ben, non, parce que ce n'est pas le même modèle de mémoire.
Un TYPE param[4][64], ce sont 4*64 objets de type TYPE
contigus en mémoire.
Un TYPE* param[4], c'est un tableau de 4 pointeurs, qui
désignent dans ton cas 4 zones mémoires de 64 objets contigus
allouée par malloc.
Les probabilités pour les 4 mallocs aient sortis 4
résultats contigus sont très faibles...

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.

Avatar
Pierre Maurette
Bernie wrote:

Par contre le prb reste ouvert, et sous une forme + générale,
est-il possible de passer une var déclarée TYPE* toto[4] à une fonction qui
explicite que son param est TYPE param[4]64] ?



Ben, non, parce que ce n'est pas le même modèle de mémoire.
Un TYPE param[4][64], ce sont 4*64 objets de type TYPE
contigus en mémoire.
Un TYPE* param[4], c'est un tableau de 4 pointeurs, qui
désignent dans ton cas 4 zones mémoires de 64 objets contigus
allouée par malloc.
Les probabilités pour les 4 mallocs aient sortis 4
résultats contigus sont très faibles...
Oui, exact. Et j'étais en core allé trop vite.

Bon, faut en sortir:

short* toto[4];
toto[0] = (short*)malloc(4 * 64 * sizeof(short));
toto[1] = toto[0] + 64;
toto[2] = toto[1] + 64;
toto[3] = toto[2] + 64;

--
Pierre


Avatar
screetch
Marc Boyer wrote:
Bernie wrote:

Par contre le prb reste ouvert, et sous une forme + générale,
est-il possible de passer une var déclarée TYPE* toto[4] à une fonction qui
explicite que son param est TYPE param[4]64] ?



Ben, non, parce que ce n'est pas le même modèle de mémoire.
Un TYPE param[4][64], ce sont 4*64 objets de type TYPE
contigus en mémoire.
Un TYPE* param[4], c'est un tableau de 4 pointeurs, qui
désignent dans ton cas 4 zones mémoires de 64 objets contigus
allouée par malloc.
Les probabilités pour les 4 mallocs aient sortis 4
résultats contigus sont très faibles...

Marc Boyer
Qui programme en proba ici?


j'imagine bien les gens dire : "mon programme a une chance sur 10 de
marcher... lancez le dix fois" ^_^

sinon, effectivement, un [4][64] et comme un [4*64] en mémoire, alors
qu'un *[4] contient de la place pour 4 pointeurs sur des tableaux de
taille inconnue du coup

c'est ce qui permet de faire des tableaux de chaine de caracteres


Avatar
Bernie
"Pierre Maurette" a écrit dans le message de
news:42403f1e$0$2128$
Bernie wrote:

Par contre le prb reste ouvert, et sous une forme + générale,
est-il possible de passer une var déclarée TYPE* toto[4] à une fonction
qui



explicite que son param est TYPE param[4]64] ?



Ben, non, parce que ce n'est pas le même modèle de mémoire.
Un TYPE param[4][64], ce sont 4*64 objets de type TYPE
contigus en mémoire.
Un TYPE* param[4], c'est un tableau de 4 pointeurs, qui
désignent dans ton cas 4 zones mémoires de 64 objets contigus
allouée par malloc.
Les probabilités pour les 4 mallocs aient sortis 4
résultats contigus sont très faibles...
Oui, exact. Et j'étais en core allé trop vite.

Bon, faut en sortir:

short* toto[4];
toto[0] = (short*)malloc(4 * 64 * sizeof(short));
toto[1] = toto[0] + 64;
toto[2] = toto[1] + 64;
toto[3] = toto[2] + 64;

--
Pierre


Ben avec ses 3 dernières reponse, j'ai l'explication, la syntaxe du cast et
la manière de conserver mes algos [4][64] tout en allouant correctement ....

merci à tous.



Avatar
Fabien LE LEZ
On Tue, 22 Mar 2005 16:09:43 +0100, "Bernie" :

soit une variable short* toto[4], qqsoit i toto[i] = (short*)malloc(64);


Je ne comprends pas bien comment tu te retrouves avec ce genre de code
dans un programme en C++.
Je veux bien admettre que tu utilises une fonction écrite en C, et que
tu te retrouves à appeler une fonction dont le prototype est
"void f(short param[4][64])". Mais a priori, la variable que tu crées
dans ton programme est un conteneur quelconque, dont le constructeur
s'occupe d'allouer la mémoire. Et comme tu as besoin de passer les
données sous forme d'un seul bloc (i.e. variables contiguës en
mémoire), il y a des chances pour que la réprésentation interne idéale
soit un std::vector<>.

J'ai bricolé un vague truc qui devrait permettre de faire ça. Pas le
temps de tester, donc il y a vraisemblablement des erreurs, mais le
principe général est là.

/* La définition de "Tableau_2D" est plus bas, mais doit bien sûr être
insérée ici */

void Encapsule_f (Tableau_2D<short>& table)
{
f (& (table.GetRawData()));
}


Tableau_2D<short> toto (64, 4);
Encapsule_f (toto);







template <class T> class Tableau_2D
{
Tableau_2D (size_t nb_elements_par_ligne_,
size_t nb_lignes_, T const& t= T())
: data (nb_lignes_ * nb_elements_par_ligne_, t)
, nb_lignes (nb_lignes_)
, nb_elements_par_ligne (nb_elements_par_ligne_)
{}

size_t NumElement (size_t x, size_t y) const
{ return x + y * nb_elements_par_ligne; }
T& operator() (size_t x, size_t y)
{ return data.at (NumElement (x,y)); }
T const& operator() (size_t x, size_t y) const
{ return data.at (NumElement (x,y)); }

typedef std::vector<T> Data;

typedef Data::const_iterator const_iterator;
typedef Data::iterator iterator;

const_iterator begin() const { return data.begin(); }
const_iterator end() const { return data.end(); }
iterator begin() { return data.begin(); }
iterator end() { return data.end(); }

size_t NbLignes() const { return nb_lignes; }
size_t NbElementsParLigne() const { return nb_elements_par_ligne; }

T* GetRawData() { return & (data.at(0)); }

private:
Data data;
size_t nb_lignes;
size_t nb_elements_par_ligne;
};



--
;-)

Avatar
James Kanze
Fabien LE LEZ wrote:
On Tue, 22 Mar 2005 16:09:43 +0100, "Bernie" :


soit une variable short* toto[4], qqsoit i toto[i] = (short*)malloc(64);



Je ne comprends pas bien comment tu te retrouves avec ce genre
de code dans un programme en C++.


Disons que la discussions qui s'en sont suivi, c'est un sacré
argument en faveur de std::vector:-).

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34


Avatar
Horst Kraemer
"Bernie" wrote:

Bonjour,
J'ai déjà rencontré ce prb et je l'avais solutionné de manière "batarde",
mais à force je me dis qu'il faudrait que je découvre un peu le fond du
prb....

soit une variable short* toto[4], qqsoit i toto[i] = (short*)malloc(64);
soit une fonction f déclarée par : void f(short param[4][64]);

comment caster "proprement" la variable toto pour la passer à f ?


Impossible parce que les structures des données sont incompatibles. La
structure de toto est différente de la structure attendue par param.
Un cast d'un pointeur ne peut changer que le *type* du pointeur. Il ne
peut pas changer la structure des données sous le pointeur.

La structure de toto est

séquence de 4 pointeurs. Chacun des pointeurs pointe vers le
premier élement d'un tableau de 64 short qui est situé quelque
part dans la mémoire par malloc.


Quel que soit ton "cast" tu passeras toujours un pointeur qui
représente l'adresse du premier *pointeur* de la séquence des 4
pointeurs.

La structure que param attend est

pointeur vers le premier élement d'une séquence de tableaux de 64
short.

Donc l'adresse passée a la fonction doit être l'adresse du premier
short du premier tableau. (on pourrait la passer mais alors les trois
autres tableaux ne seront pas consécutifs dans la mémoire).

Pour passer la structure de ton 'toto' il faudrait que la fonction ait
un paramètre du type

short ** param

ou

short * param[4]


Le paramètre 'param' de la fonction est équivalent à

short (*param) [64]


Donc une structure passée a ta fonction *doit* correspondre à un
tableau de 4 tableaux de 64 short, donc à une séquence de tableaux de
64 short.


p.ex.

short (*toto) [64] = malloc (4* sizeof *toto);

Ici short est un pointeur vers le premier élément d'un tableau de 4
tableaux de 64 short, tandis que ton "toto" était un (pointeur vers le
premier élément d'un) tableau de 4 pointeurs vers les premiers
élements de tableaux de 64 short.

Il faut donc ou bien changer toto ou param. Un cast n`y peut rien.

ouf,,,

--
Horst

--
Lâche pas la patate!

1 2 3 4