Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

array bound forbidden after parenthesized type-id

57 réponses
Avatar
Lucas Levrel
Bonjour,

J'utilise des objets alloués dynamiquement comme suit :
double (*data)[3];
data=new double[t][3];

Maintenant, je voudrais en faire un tableau. J'essaye donc :

double (**tab)[3];
tab=new (double(*)[3])[n];
for(int i=0;i<n;i++) tab[i]=new double[t][3];

et le compilateur (g++) me donne l'erreur que j'ai mise en sujet.
Est-ce que le code suivant, qui compile sans erreur, est équivalent à ce
que je veux faire ?

typedef double(*data_type)[3];
data_type *tab;
tab=new data_type[n];
for...

Si oui, pourquoi le compilateur refuse-t-il le premier code et pas le
second ?

Merci d'avance.
--
LL

10 réponses

2 3 4 5 6
Avatar
Fabien LE LEZ
On Thu, 23 Jul 2009 08:28:59 -0500, Gabriel Dos Reis
:

ah mais, tu montres que tu es homme quand tu le fais tout seul avec tes
petites mains :-p



Les vrais mecs ne programment pas en C++. Ils programment en
assembleur.

"I write all of my software in 100% pure assembly language — the raw
native language of the Intel microprocessor. I use it because, as the
actual language of the system, it requires no inefficient translation
from an easier-to-use "high level" language."
https://www.grc.com/unpnp/unpnp.htm
Avatar
Gabriel Dos Reis
Lucas Levrel writes:

| Le 23 juillet 2009, Fabien LE LEZ a écrit :
| > Il me semble qu'en pratique, vector<> alloue juste ce qu'il faut de
| > mémoire, tant que tu ne changes pas la taille en cours de route. À
| > vérifier.
|
| Tu as raison, du moins ici c'est ce que je trouve (g++).

Un vector<T> (même vide) occupe au minimum 3 mots.

-- Gaby
Avatar
Lucas Levrel
Le 23 juillet 2009, Gabriel Dos Reis a écrit :
Un vector<T> (même vide) occupe au minimum 3 mots.



Sur un vector de 100 Mo je n'ai pas vu la différence... Ce que je ne veux
pas, c'est que l'espace alloué initialement ait une marge proportionnelle
à la taille demandée, par exemple capacity=1.2*size.

--
LL
Avatar
Gabriel Dos Reis
Lucas Levrel writes:

| Le 23 juillet 2009, Gabriel Dos Reis a écrit :
| > Un vector<T> (même vide) occupe au minimum 3 mots.
|
| Sur un vector de 100 Mo je n'ai pas vu la différence...

Je répondais à l'observation

# > Il me semble qu'en pratique, vector<> alloue juste ce qu'il faut de
# > mémoire, tant que tu ne changes pas la taille en cours de route. À
# > vérifier.

-- Gaby
Avatar
Lucas Levrel
Le 24 juillet 2009, Gabriel Dos Reis a écrit :

Lucas Levrel writes:

| Le 23 juillet 2009, Gabriel Dos Reis a écrit :
| > Un vector<T> (même vide) occupe au minimum 3 mots.
|
| Sur un vector de 100 Mo je n'ai pas vu la différence...

Je répondais à l'observation

# > Il me semble qu'en pratique, vector<> alloue juste ce qu'il faut de
# > mémoire, tant que tu ne changes pas la taille en cours de route. À
# > vérifier.



OK, mais le fait qu'un vector<> vide occupe 3 mots ne signifie pas qu'il a
alloué de la mémoire *pour les données*. Autrement dit, une coquille d'œuf
a une masse même si elle est vide. :-)

--
LL
Avatar
James Kanze
On Jul 23, 10:23 am, Fabien LE LEZ wrote:
On Thu, 23 Jul 2009 00:34:46 -0700 (PDT), James Kanze
:



>À condition de ne pas vouloir rélire les données plus tard,
>avec un autre programme, ou sur une autre machine.



On n'a pas beaucoup de garanties, effectivement.
Néanmoins, il s'agit d'enregistrer des "double", contigus. Il
y a de bonnes chances pour que ça fonctionne bien tant qu'on
reste sur des architectures i386 ou AMD64. Et dans pas mal de
cas, ça suffit largement.



Je ne sais pas. Microsoft a déjà changé la représentation d'un
long entre deux versions du compilateur. Mais je crois bien
qu'il pêche de l'autre côté aujourd'hui ; quelle autre raison
invoquer pour quelque chose d'aussi stupide que de faire un long
de 32 bits sur une machine 64 bits ? Alors, tu as peut-être
raison, même si c'est une mauvaise habitude à prendre. À ne
faire quand même qu'avec les float et les double, et que si le
code contient tellement de Microsoftismes qu'il ne pourrait
de toute façon jamais être porté à un autre système. (Moi, par
exemple, jusqu'il y a six mois environ, je travaillais plus sur
des Sparc que sur des Intel/AMD.)

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
James Kanze
On Jul 23, 11:39 am, Lucas Levrel
wrote:
Le 23 juillet 2009, James Kanze a écrit :



> > De plus, ça m'arrange que les doubles soient contigus par
> > paquets de t*3, pour faire une écriture non formatée
> > comme :
> > file_out.write((char*)tab[i],t*3*sizeof(double));



> Ce qui ne marche en aucun cas. (snip)



Pourquoi ? Je parlais du cas où je fais new double[t][3]. Dans
ce cas il est garanti que les doubles sont contigus et que le
pointeur retourné pointe sur le premier de ces doubles,
n'est-ce pas ?



Les doubles sont bien contigus, mais il n'y a aucune garantie en
ce qui concerne leur représentation. J'ai déjà vu la
représentation d'un long change d'une version du compilateur à
l'autre, et pour les types plus complex, la représentation
pourrait changer même selon les options de la compilation.

> > Tout ça m'a conduit à l'idée de faire des new double[t][3]
> > et un tableau de n pointeurs vers ceux-ci.



> Pourquoi le tableau de pointeurs ?



Par rapport à quoi ? Comme je ne connaissais pas vector et
qu'on ne peut pas faire new double[n][t][3], je ne voyais pas
quoi faire d'autre.



Aha. Je ne me suis pas rendu compte que t n'était pas constante
(ou je ne m'y suis pas pensé, étant donné que j'aurais sans
doute fait une classe autour d'une std::vector<double>, avec
calcul des indices).

> Je ne sais pas encore exactement quelle structure de données
> tu veux. double[n][t][3], avec la garantie que double[3][t]
> soit contigu ?



Oui (enfin, double[t][3] contigu).



std::vector< double > var( 3 * t ) ;

Ferais alors l'affaire, non. Dans une classe qui implémente ce
qu'il faut pour operator[].

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
James Kanze
On Jul 23, 3:28 pm, Gabriel Dos Reis wrote:
James Kanze writes:



> On Jul 22, 5:19 pm, (Pascal J.
> Bourguignon)> wrote:



> > Fabien LE LEZ writes:



> > En fait, rien n'empêche de définir une classe (template)
> > specifique pour des tableaux multidimentionnel. C'est
> > juste une question d'imagination, mais il semble bien que
> > les programmeurs C++ n'en soit pas capables, et se
> > ramênent toujours à des vecteurs de vecteurs qu'ils ont
> > appris à faire en C...



> C'est plutôt une question de ne pas réinventer la roue.
> C'est un peu stupide de réécrire un tas de code, quand j'ai
> une implémentation tout faite qui marche.



ah mais, tu montres que tu es homme quand tu le fais tout seul
avec tes petites mains :-p



Et puis, réécrire une classe de vecteur pour l'n-ième fois,
c'est bien plus simple de s'attaquer aux problèmes réels qu'a le
client. Et peut-être plus rentable, aussi, parce que par la
suite, il n'y a que moi qui comprendrai le code -- il faut donc
que le client s'adresse à moi pour tout modification, que je
pourrais facturer assez cher.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
James Kanze
On Jul 23, 10:26 am, Fabien LE LEZ wrote:
On Thu, 23 Jul 2009 00:11:00 -0700 (PDT), James Kanze
:



>Ou simplement un vector< T >, avec calcule de l'indice.



C'est plus compliqué -- vu qu'il faut calculer l'indice à
chaque accès. Cette complication est justifiable dans certains
cas (surtout quand on se préoccupe de l'occupation mémoire),
mais dans le cas général, c'est s'emmerder pour pas
grand-chose.



Et c'est plus simple, parce que tu n'as pas à s'occuper à
générer les éléments supplémentaires, ni de assurer qu'ils aient
tous la même taille. C'est plutôt une question de goût, je
crois. (Évidemment, le calcul de l'indice ne se fait que dans un
seul endroit, dans l'opérateur [] de la classe qui contient le
vecteur.)

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
Gabriel Dos Reis
Lucas Levrel writes:

| Le 24 juillet 2009, Gabriel Dos Reis a écrit :
|
| > Lucas Levrel writes:
| >
| > | Le 23 juillet 2009, Gabriel Dos Reis a écrit :
| > | > Un vector<T> (même vide) occupe au minimum 3 mots.
| > |
| > | Sur un vector de 100 Mo je n'ai pas vu la différence...
| >
| > Je répondais à l'observation
| >
| > # > Il me semble qu'en pratique, vector<> alloue juste ce qu'il faut de
| > # > mémoire, tant que tu ne changes pas la taille en cours de rout e. À
| > # > vérifier.
|
| OK, mais le fait qu'un vector<> vide occupe 3 mots ne signifie pas qu'il a
| alloué de la mémoire *pour les données*.

3 mots pour représenter un vecteur vide n'est pas exactement ce que je
qualifierais de « alloue juste ce qu'il faut de mémoire. »

-- Gaby
2 3 4 5 6