OVH Cloud OVH Cloud

Tableau dynamique

75 réponses
Avatar
Pierre CHAUVEAU
Bonjour à toutes et à tous,

Personnellement, je réalise mes programmes avec DELPHI (langage Pascal de
BORLAND) où sont définis des "tableaux dynamiques". Ce sont des tableaux
dont on peut fixer la taille (le nombre d'éléments) à l'exécution.

J'utilise ce type de tableaux pour échanger des infos entre un programme et
des DLL.

Existe-t-il l'équivalent, pour ne pas dire la même chose, dans d'autres
langages, notamment le C++ de chez Microsoft.

Sinon, comment faites-vous pour échanger entre .exe et .dll quand vous ne
connaissez pas à la compilation la taille des infos à échanger ;le nombre de
pixels de l'image en cours de traitement par exemple.

Merci de votre aide.

Pierre.

10 réponses

1 2 3 4 5
Avatar
Bertrand Lenoir-Welter
> et ton pointeur est un void* ? Dans ce cas, un malloc est possible,
mais ton pointeur va prendre des risques... voir dessous.



Mon pointeur peut être n'importe quoi qui pointe. Il risque pas de
prendre des risques si je programme proprement. Il est effectivement
"préférable" que ceux qui programment avec les pieds n'emploient pas des
méthodes qui requièrent un minimum de sérieux. Nul n'entre ici s'il ne
s'essuie pas les pieds.


1) si new échoue alors lancement d'une exception... et le programme
s'arrete proprement si on ne teste rien.



Un programme qui s'arrête proprement, ça fait une belle jambe à
l'utilisateur. "Coucou, ce programme vient de s'arrêter, mais
proprement, hein."


Si malloc échoue alors ça renvoie NULL, et ça plante si on ne teste pas.



T'es en train de dire qu'un débile mental ne devrait pas utiliser le
malloc. Moi je pense qu'un débile mental ne devrait pas programmer, et
en tout cas pas en C++.


2) malloc renvoie un void* donc pas de typage fort du pointeur.



Quel besoin de typage puisque par définition tu demandes de la mémoire
en vrac et non pas une structure préalablement définie ?


Tu est obligé de faire un cast "sauvage" (statique, quoi) et souvent
ça masque des futurs problèmes...



Ben voyons... Tu vas m'expliquer lentement en quoi j'aurais un problème
si j'ai proprement défini un tableau d'octets simples dont je connais
pas la taille, que j'alloue avec malloc - en vérifiant qu'il a bien été
alloué, mais oui mon bon Monsieur, ah y'a un peu plus, je vous le mets
quand même ? - et que je manipule ensuite avec un cast pour taper
dedans. Je cherche les futurs problèmes masqués, mais je les vois pas.
Me faudrait de bonnes oeillères.

Note que tu peux avoir les mêmes soucis de casting avec du new. J'ai par
exemple une liste chaînée dont chaque structure contient entre autres un
pointeur void* parce que je sais pas à l'avance ce qui va aller dedans
et même s'il va aller quelque chose ou si ça va rester inutilisé.
Allocation avec new, bien que le type soit indéfini. Futurs problèmes ?
Ca fait 5 ans que ça tourne comme ça.


struct C1 { /*....*/ };
struct C2 {/*....*/}; autre objet de taille différente
C1* ptr_mal_alloue = (C1*)malloc(sizeof(C2)); // AIE AIE !!!



Fastoche. Il me semblait avoir bien précisé que j'utilisais justement le
new quand ma structure allouée était fixe, et malloc quand j'avais un
tableau à taille variable, par exemple une ligne dans un fichier texte.
Ton exemple est un peu raccourci, non ?


C1 *ptr_qui_compile_pas = new C2; // ici le compilo bloque, normal !



Puisqu'on en est à tirer les exemples par les cheveux :
C1 *ptr_qui_compile=(ptr_qui_compile*)new(C2); // Même pas un warning


Ma conclusion seconde est que ma conclusion première était bonne : avec
une structure définie (ou un tableau alloué dynamiquement mais à taille
connue à la compilation), c'est new ; avec un tableau à taille connue
seulement à l'exécution, c'est malloc ; et pour ceux qui se
contrefichent de programmer proprement, c'est l'ANPE.
Avatar
Vincent Burel
"Patrick D." <patrickr.dubois.don' wrote in message
news:
On Sun, 14 Nov 2004 08:23:42 +0100, Vincent Burel
wrote:

> Ce choix là, vous regarde, ceci dit le NEW ne peut pas servir à faire un
> tableau dynamique, il peut éventuellement servire à hinstancier un objet
> de
> gestion de tableau dynamique, voire hinstancier les objets qui seront
> stocker dans un tableau dynamique... Mais encore une fois vous faites
> confusion. C'est comme si je disais, "New sert à faire un jeu vidéo".
>

manifestement tu as pris l'habitude de préfixer tes variables d'instance
avec le préfixe 'hinst' . c'est bien.
de là à en faire dériver un verbe en français ....

'instancier' et non 'hinstancier'
je me demande d'ailleurs si ce verbe existe en dehors du jargon
informatique.

vu le nombre d'utilisations que tu en as faites, je n'ai pu m'empêcher
d'instancier cette correction !



Judicieux !
Et tellement utile...
Avatar
Loïc Joly
Bertrand Lenoir-Welter wrote:

en C++ un new est préférable à un malloc.




Et c'est gravé dans quel marbre, ce dogme ?

Je code en C++ et j'utilise new quand j'ai un type fixe derrière, par
exemple une structure pour une liste chaînée - donc à taille fixe. Mais
quand j'ai une allocation dont la taille dynamique m'est fournie par une
variable, par exemple pour loger un bloc d'octets élastique, alors
retour au bon vieux malloc. Honte à moi.

Au fait, ce "préférable", ça veut dire quoi exactement ?



new sait faire tout ce que malloc sait faire. Mais il sait aussi faire plus.

Par exemple, il sait construire les objets. Si tu as des tableaux
dynamiques d'objets, malloc ne te sera d'aucune aide, si tu n'as pas un
new pour t'aider (à lire par là qu'on peut éventuellement utiliser
malloc + placement new, si on veut décorréler allocation de création,
tout comme on peut aussi utiliser new char[] puis placement new, ou
encore new[] tout court, mais un new est nécessaire).

On peut aussi définir un objet pour qu'il alloue sa mémoire de manière
autre que standard, et dans ce cas, new fera automatiquement ce qu'il
faut faire, alors que malloc sera bien embêté.


En C++ l'utilisation d'un std::vector est préférable à un new pour
faire un tableau dynamique.




Indubitablement. Et des oeillères sont préférables pour ne pas avoir un
horizon trop large. Je dois être de la vieille école.



Je ne pense pas, je connais des gens de la vieille école qui préfèrent
choisir l'outil adapté, plutôt que se limiter au seul outil qu'ils
connaissent.

--
Loïc
Avatar
Loïc Joly
AMcD® wrote:

Alexandre wrote:


1) si new échoue alors lancement d'une exception... et le programme
s'arrete proprement si on ne teste rien.




C'est les nazes qui programment sans vérifier les retours de fonctions...



Probablement.

Le problème que cherchent à résoudre les exceptions n'est pas celui là.
C'est plutôt que comme en général, l'endroit de détection de l'erreur et
l'endroit où on peut la traiter sont séparés, tester les valeurs de
retour de totutes les fonctions que l'on appelle, et reporter l'erreur
en question à la fonction qui nous a appelé demande en général beaucoup
de code, après avoir manuellement libéré toutes les ressources allouées
dans chaque cas.

Les exceptions font que ce code répétitif et sans plus value
intellectuelle est géré par le compilateur automatiquement. On simplifie
alors la complexité du code, en évitant que 75% d'une fonction ne soit
là que pour gérer les cas à problème.

--
Loïc
Avatar
Loïc Joly
Bertrand Lenoir-Welter wrote:

Ben voyons... Tu vas m'expliquer lentement en quoi j'aurais un problème
si j'ai proprement défini un tableau d'octets simples dont je connais
pas la taille, que j'alloue avec malloc - en vérifiant qu'il a bien été
alloué, mais oui mon bon Monsieur, ah y'a un peu plus, je vous le mets
quand même ? - et que je manipule ensuite avec un cast pour taper
dedans. Je cherche les futurs problèmes masqués, mais je les vois pas.
Me faudrait de bonnes oeillères.



Si tu alloue un tableau d'octets, puis que tu fais croire à ton
compilateur que tu as des objets à l'intérieur en castant, tu as alors
un comportement indéfini.


Note que tu peux avoir les mêmes soucis de casting avec du new. J'ai par
exemple une liste chaînée dont chaque structure contient entre autres un
pointeur void* parce que je sais pas à l'avance ce qui va aller dedans



C'est souvent considéré comme un mauvais style en C++, qui offre des
outils pour gérer ça de manière plus simple.

[...]

Ma conclusion seconde est que ma conclusion première était bonne : avec
une structure définie (ou un tableau alloué dynamiquement mais à taille
connue à la compilation), c'est new ; avec un tableau à taille connue
seulement à l'exécution, c'est malloc ; et pour ceux qui se
contrefichent de programmer proprement, c'est l'ANPE.



Montre moi comment tu alloues un tableau dynamique d'objets de type C
sans utiliser new. Ce n'est pas possible.

--
Loïc
Avatar
Loïc Joly
Vincent Burel wrote:


C'est une confusion classique chez les "pseudo-programmeur" C++, je le
répète donc, le NEW en C++ sert à hinstancier, créer et déclencher l'appel
du constructeur d'un object de type C++. le Malloc est une fonction qui
permet d'allouer de la mémoire. Donc, il n'y a pas grand rapport avec ces
deux fonctions, ou plutot fonctionnalités, car "malloc" est une fonction
d'un librairie, "new" est un mot réservé du langage...



C'est un peu plus compliqué. En C++, new est à la fois un mot clef et un
opérateur (et par conséquent une fonction) qui peut être surchargé.
De plus, new peut servir à allouer de la mémoire uniquement (avec les
types de base), à allouer de la mémoire et construire des objets (le
plus classique, avec des UDT), ou encore à construire des objets
uniquement dans un emplacement mémoire préalloué (placement new).


En C++ l'utilisation d'un std::vector est préférable à un new pour faire



un

tableau dynamique.




Ce choix là, vous regarde, ceci dit le NEW ne peut pas servir à faire un
tableau dynamique,



Ah bon ? Que penser de ce code ?

int f()
{
int taille;
cin >> taille;
char *chaine = new char[taille];
delete[] chaine;
}


il peut éventuellement servire à hinstancier un objet de
gestion de tableau dynamique, voire hinstancier les objets qui seront
stocker dans un tableau dynamique... Mais encore une fois vous faites
confusion. C'est comme si je disais, "New sert à faire un jeu vidéo".



--
Loïc
Avatar
David MAREC
D'après AMcD®:

Déjà le gars il à qu'a coder proprement genre PC1 au lieu de C1*, ce sera
plus lisible.



bof.
Avatar
AMcD®
Loïc Joly wrote:

Si tu alloue un tableau d'octets, puis que tu fais croire à ton
compilateur que tu as des objets à l'intérieur en castant, tu as alors
un comportement indéfini.



Ben ça dépend de quel compilo tu utilises, de quel genre de code tu écris.
Moi, en C ou ASM, il m'arrive souvent de déclarer simplement une zone de
mémoire et... de choisir ensuite si c'est des BYTE, WORD, LONG, objets,
caractères ou je ne sais quoi. Cela dépend de tellement de choses...

La programmation c'est pas un art guidé par des dogmes et des oeillères. Tu
ne peux pas dire c'est comme ça et pas autrement. Il y a tellement de
domaines d'application, de domaines, de contextes particuliers...

Au passage, les compilos font ça souvent hein, regarde les unions en C/C++
:-)

--
AMcD®

http://arnold.mcdonald.free.fr/
Avatar
AMcD®
David MAREC wrote:
D'après AMcD®:

Déjà le gars il à qu'a coder proprement genre PC1 au lieu de C1*, ce
sera plus lisible.



bof.



Ben code des softs de plusieurs 100K lignes, tu verras si t'oublies plus
souvent un * ou si tu confonds plus souvent un C1 et un C2 :-)

De toute façons, appeler un type C1 hein...

--
AMcD®

http://arnold.mcdonald.free.fr/
Avatar
Vincent Burel
"Loïc Joly" wrote in message
news:41974eb9$0$5863$
Vincent Burel wrote:


> C'est une confusion classique chez les "pseudo-programmeur" C++, je le
> répète donc, le NEW en C++ sert à hinstancier, créer et déclencher


l'appel
> du constructeur d'un object de type C++. le Malloc est une fonction qui
> permet d'allouer de la mémoire. Donc, il n'y a pas grand rapport avec


ces
> deux fonctions, ou plutot fonctionnalités, car "malloc" est une fonction
> d'un librairie, "new" est un mot réservé du langage...

C'est un peu plus compliqué. En C++, new est à la fois un mot clef et un
opérateur (et par conséquent une fonction) qui peut être surchargé.
De plus, new peut servir à allouer de la mémoire uniquement (avec les
types de base), à allouer de la mémoire et construire des objets (le
plus classique, avec des UDT), ou encore à construire des objets
uniquement dans un emplacement mémoire préalloué (placement new).



oui, cependant, les type de base du ++, sont d'abord des objets. et le new
sert à créer des objets, de manière dynamique... c'est à dire sur demande.
Qu'il y ait allocation mémoire ou pas, non seulement vous n'êtes pas
susceptible de le savoir (après tout l'utilisateur du C++ n'est pas
programmeur, pourquoi devrait -il connaitre des détails qui concernent une
machine ou un systeme en particulier !? ), mais en plus ca n'a rien
d'évident... on peut concevoir des architecture où la création d'un objet
n'engendre pas d'allocation mémoire...


> Ce choix là, vous regarde, ceci dit le NEW ne peut pas servir à faire un
> tableau dynamique,

Ah bon ? Que penser de ce code ?

int f()
{
int taille;
cin >> taille;
char *chaine = new char[taille];
delete[] chaine;
}



J'en pense que, comme d'habitude, mes formulations aident à faire sortir
l'imbécile de sa tanière :-) Alors puisque vous avez envie de parler,
remarquez donc que la variable taille vous sert aussi à créer votre tableau,
ainsi que les crochets [], de même que sans l'affectation, représentée par
le signe '=' vous ne pouriez pas vous servir de votre tableau, est-ce à dire
que l'affectation sert à créer des tableaux... Je vous laisse répondre :-)

VB

PS : juste pour voir si vraiment il reste des troller sur ce newsgroup :-)
1 2 3 4 5