#1 Le 27/11/2010, à 08:34
- Jules Petibidon
[C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Salut les gens,
Histoire de m'initier à C++, je suis en train de traduire un petit algo depuis Java vers C++.
Et je me suis cassé les dents sur une fonction qui doit me retourner un tableau.
Comment on déclare ce genre de chose ?
L'idée par exemple pour des entiers :
int[] mafonction( int[] );
Comme de bien entendu ça fonctionne pas.
Je m'en suis sorti en utilisant un pointeur, histoire de vérifier que l'algo fonctionne correctement, mais bon, ça me chagrine tout de même de pas savoir comment gérer le truc avec un tableau.
Si la question est pas claire, disez le, j'essayerai d'expliquer mieux
Dernière modification par Jules Petibidon (Le 27/11/2010, à 21:07)
Hors ligne
#3 Le 27/11/2010, à 09:21
- omc
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Bonjour,
Si tu fais du C++ évite les tableau à la C (comme tu le fais).
Tu peux utiliser les tableau (le terme exact est conteneur) de la lib standart du C++ comme les vectors.
#include <vector>
.....
.....
.....
std::vector<int> mafonction(std::vector<int> );
// ou mieux... en utilisant des références
std::vector<int>& mafonction(std::vector<int>& );
Hors ligne
#4 Le 27/11/2010, à 09:29
- Jules Petibidon
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Merci de ta réponse,
Mais pour ce qui est de la déclaration d'un tableau c'est pas trop un soucis, c'est plutôt au niveau de la déclaration d'une fonction.
Un truc du genre :
maFonction(){
int monTableau[ 100 ];
return monTableau;
}
Quel est le proto ?
J'ai peut-être de la merde dans les yeux, mais j'ai pas trouvé un seul tuto qui réponde à ça
@omc, nos messages se sont croisés (j'ai rédigé longtemps pour trouver la bonne formulation ).
En pratique ok, je suivrai ton conseil Là la question est plutôt pour la "culture", je m'étonne de ne pas pouvoir faire ce genre de truc simple en fait.
Dernière modification par Jules Petibidon (Le 27/11/2010, à 09:33)
Hors ligne
#5 Le 27/11/2010, à 13:56
- omc
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Avec les mots clés "C array" tu ne trouves pas ?
Sinon pour ton soucis, le type
int tab[100];
est en fait un pointeur sur un entier, soit
int *
Donc la bonne syntaxe du prototype est
int* maFonction();
Hors ligne
#6 Le 27/11/2010, à 15:22
- grim7reaper
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Non, même avec un prototype
int* maFonction();
Le code
int monTableau[ 100 ];
return monTableau;
est faux car tu vas renvoyer l'adresse d'une variable locale.
Il faudra passer par de l'allocation dynamique (une solution parmis d'autre), mais comme on est en C++ je plussoie l'utilisation des std::vector.
Sinon, dire que
int tab[100]
est équivalent à
int*
est faux.
Dernière modification par grim7reaper (Le 27/11/2010, à 15:23)
Hors ligne
#7 Le 27/11/2010, à 15:41
- Jules Petibidon
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
J'avais essayé avec int* maFonction, ce qui en effet n'était pas concluant
Donc à la lumière de ce que vous dites, j'en déduis qu'il n'est pas possible de faire cela (de façon simple j'entends) et qu'il est préférable de passer par un vecteur ou un pointeur sur un tableau externe (ce qui est finalement pas si compliqué, faut s'habituer c'est tout)
Comme dit en titre, je découvre C++... Quant à C, j'ai pas goûté longtemps, sans OO je suis trop malheureux
Donc pour poursuivre cette discussion, ayant contourné le point 1 avec un pointeur, je me retrouve avec un problème étrange.
L'algo sur lequel je travaille est un tri par arbre binaire ( naïf ).
Je rentre une série de nombres aléatoires, il me ressort un tableau trié. Au delà de 2 000 000 de nombres à trier (ce qui représente environ 50 000 000 d'opérations pour le tri), il plante à l'exécution, pas de messages d'erreur, rien.
Est ce un dépassement de capacité quelconque sur quoi que ce soit ? Ne devrait il pas y avoir un message dans ce cas ?
Hors ligne
#8 Le 27/11/2010, à 15:43
- grim7reaper
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
S'il plante vraiment, il devrait y avoir un message d'erreur.
Il plante vraiment, ou il ne s'arrête pas (peut-être une boucle infinie) ?
Sinon, le mieux c'est de poster le code fautif (ou s'il est trop gros, un code minimal et compilable qui reproduit le problème).
Dernière modification par grim7reaper (Le 27/11/2010, à 15:56)
Hors ligne
#9 Le 27/11/2010, à 15:55
- Jules Petibidon
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Hmm, je testais depuis Eclipse, pas de message d'erreur. En testant directement en console je finis par avoir une erreur de segmentation.
Le code incriminé ~70 lignes, sans les .h et annexes (comme ça vous pourrez aussi me dire si ce code est un "correct" C++ ou trop influencé par Java :
#include <cstdlib>
#include <iostream>
#include "ArbreTrie.h"
ArbreTrie::ArbreTrie( int val , Compteur * cpt ) {
valeur = val;
compteur = cpt;
}
ArbreTrie::~ArbreTrie() {
// TODO Auto-generated destructor stub
}
void ArbreTrie::inserer( int val ){
compteur->inc();
if( val <= valeur ){
if( gauche == NULL ){
gauche = new ArbreTrie( val , compteur );
}
else gauche->inserer( val );
elementsG++;
}
else{
if( droite == NULL ){
droite = new ArbreTrie( val , compteur );
}
else{
droite->inserer( val );
}
elementsD++;
}
}
unsigned int ArbreTrie::nbElements() const{
return elementsG + elementsD;
}
int* ArbreTrie::exporter( int *pListe ){
if( gauche != NULL ){
pListe = gauche->exporter( pListe );
}
*pListe = valeur;
pListe++;
if( droite != NULL ){
pListe = droite->exporter( pListe );
}
return pListe;
}
int main(){
ArbreTrie *arbre1 = NULL;
Compteur *cpt = new Compteur();
for( int i = 0 ; i < 5000000 ; i++ ){
if( arbre1 == NULL ){
arbre1 = new ArbreTrie( rand() , cpt );
}
else{
arbre1->inserer( rand() );
}
}
int tableau[ arbre1->nbElements() ];
int *pTab = &tableau[0];
pTab = arbre1->exporter( pTab );
std::cout << "Nombre d'opérations : " << cpt->getVal() << std::endl;
/*
for( int i = 0 ; i < arbre1->nbElements() ; i++ ){
std::cout << tableau[ i ] << std::endl;
}
*/
}
Hors ligne
#10 Le 27/11/2010, à 15:58
- grim7reaper
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Il faudrai au moins avoir du code compilable.
Une erreur de segmentation est plus rapide à repérer quand on exécute le code .
Hors ligne
#11 Le 27/11/2010, à 16:16
- Jules Petibidon
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
le code complet est dispo à cette adresse :
http://bouargh.dyndns.org/liste.tar.gz
Y'a que les fichiers source, pas de makefile ou quoi ou qu'est-ce, je sais pas (encore) faire
Hors ligne
#12 Le 27/11/2010, à 16:57
- grim7reaper
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
OK, merci.
Bon déjà en C++ on n'utilise pas NULL mais 0.
Sinon, tu ne peux pas déclarer de tableau comme ça
int tableau[arbre1->nbElements()];
Sinon on obtiens ça
attention : ISO C++ forbids variable length array 'tableau'
Ce qui n'est pas bon bon et est la source de la SIGSEGV.
En effet, une telle déclaration est invalide et donc ça plante dès que tu veux écrire dans le tableau.
Pour résoudre le problème et avoir un code plus C++, je te conseille d'utiliser les vector (et de passer un itérateur à ta fonction exporter).
Autre remarque, ça
int* pTab = &tableau[0];
c'est équivalent à ça
int* pTab = tableau;
Sinon, concernant ton problème.
Je pense qu'à la base ton arbre n'est pas bien construit (j'arrive à supprimer la SIGSEGV en passant par un vector, mais l'exportation n'est pas convaincante), il vaudrait mieux vérifier ta fonction insérer car je n'ai pas l'impression qu'elle lie les fils créés à l'arbre existant.
Autre problèmes, ton constructeur n'initialise pas gauche, droite, etc…
Tant que je suis dans le contructeur, il vaudrait mieux utiliser une liste d'initialisation (mais ce n'est pas important, on y reviendra quand le bug sera corrigé).
Hors ligne
#13 Le 27/11/2010, à 17:33
- Jules Petibidon
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
C'est moi qui te remercie !
Ce qui est étonnant tout de même c'est que tout fonctionne correctement en dessous de 2M de nombres.
En bouclant sur une 20aine au lieu des 2M et en décommentant les dernières lignes, tu obtiens bien une liste triée.
Pour l'initialisation de gauche et droite, j'y penserai (là c'est vraiment de la découverte de la syntaxe et des règles de C++) et pour le pointeur de tableau, je note. Tous les tutos sur C que j'ai pu trouver utilisaient la syntaxe que j'ai utilisé, me suis pas posé plus de questions
Sinon NULL != 0 ? C'est embêtant, je trouve que la constante NULL est bien plus parlante.
Hors ligne
#14 Le 27/11/2010, à 17:53
- omc
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Sinon, dire que
int tab[100]
est équivalent à
int*
est faux.
Peux-tu expliquer Stp ?
Merci !
Hors ligne
#15 Le 27/11/2010, à 17:55
- omc
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Sinon NULL != 0 ? C'est embêtant, je trouve que la constante NULL est bien plus parlante.
Hors ligne
#16 Le 27/11/2010, à 18:40
- grim7reaper
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
grim7reaper a écrit :Sinon, dire que
int tab[100]
est équivalent à
int*
est faux.
Peux-tu expliquer Stp ?
Merci !
Bien sûr.
C'est une erreur fréquemment commise (dû à une simplification un peu rapide).
Dans beaucoup de cas, ce que tu dis semble vrai car le compilo remplace le nom du tableau par l'adresse de la première valeur.
Pour plus d'info et d'exemples, tu peux regarder ici (il y a parfois des trucs de qualité douteuses sur le SdZ, mais celui là est bon)
C'est pour le C, mais sur ce point-là le C++ fonctionne pareil.
Dernière modification par grim7reaper (Le 27/11/2010, à 18:45)
Hors ligne
#17 Le 27/11/2010, à 19:07
- omc
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
oki !
Dernière modification par omc (Le 27/11/2010, à 19:08)
Hors ligne
#18 Le 27/11/2010, à 20:08
- Jules Petibidon
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Merci pour vos réponses.
Donc pour être dans les regles, je suis passé par un premier test avec la classe vector.
Instanciation vide et utilisation intensive de pop_back. Les performances sont au mieux désastreuses, au pire ça plante bien avant le million d'entrées (ou plutôt ça doit partir en boucle infinie, j'ai eu le temps de faire cuire des sablés pendant que le programme calculait ).
Bref, c'est encore parti pour pas être simple. Il est un peu frustrant ce langage
Hors ligne
#19 Le 27/11/2010, à 20:46
- grim7reaper
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Je ne sais pas comment tu as fait, mais basiquement j'aurais fait comme ça pour migrer au vector
(Je ne poste que les modifs)
ArbreTrie.h
[…]
#include <vector>
[…]
void exporter(std::vector<int>::iterator pList);
[…]
ArbreTrie.cpp
[…]
void ArbreTrie::exporter( std::vector<int>::iterator pListe ){
if( gauche != 0 ){
gauche->exporter( pListe );
}
*pListe = valeur;
pListe++;
if( droite != 0 ){
droite->exporter( pListe );
}
}
[…]
// Dans main
std::vector<int> tableau(arbre1->nbElements());
std::vector<int>::iterator pTab = tableau.begin();
arbre1->exporter(pTab);
std::cout << "Nombre d'opérations : " << cpt->getVal() << std::endl;
for( unsigned int i = 0 ; i < arbre1->nbElements() ; i++ ){
[…]
Bon, ça ne fonctionne pas tout à fait mais l'idée est là (ça compile, c'est rapide et ça ne plante pas)
Hors ligne
#20 Le 27/11/2010, à 21:06
- Jules Petibidon
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
Au final j'ai un code qui ressemble à peu près à ça (mais corrigé pour qu'il fonctionne ).
Tout est bien qui finit bien, merci de votre aide !
Hors ligne
#21 Le 08/05/2013, à 22:19
- azare
Re : [C++] fonction qui retourne un tableau - Gros noob inside [resolu]
qu’il est le nombre total de façons possibles
de partitionner n objets en c classes différentes?
Hors ligne