newkam2013
Messages postés4Date d'inscriptionmercredi 21 août 2013StatutMembreDernière intervention22 août 2013
-
Modifié par KX le 21/08/2013 à 21:23
newkam2013
Messages postés4Date d'inscriptionmercredi 21 août 2013StatutMembreDernière intervention22 août 2013
-
22 août 2013 à 22:24
Bonjour,
Cela fait des années que je n'ai pas codé avec C++. J'ai implémenté un algorithme simple, le code compile, l'exécutable est parfait, sauf que ça crash pour des performances faibles ( tableaux 5000*3*2 par exemple). pour etre pratique, vous trouver ci-après le main du code si vous avez des propositions, sachant que je ne sais plus comment manipuler des vecteurs std::...Merci infiniment par avance!
KX
Messages postés16734Date d'inscriptionsamedi 31 mai 2008StatutModérateurDernière intervention24 avril 2024127 21 août 2013 à 21:34
Je n'ai pas vraiment regardé en détail ton code, mais dès que j'ai vu que tu faisais appel à des fonctions (H, W, etc.) je me suis dit que c'était du récursif, ce qui explique ton problème. Car même si les dimensions de tes tableaux sont relativement petites, le nombre d'appels récursifs peut facilement exploser et ainsi dépasser la taille de la pile.
Dans ton cas, essaye de remplacer les appels récursifs par des boucles, ou au minimum d'en limiter le nombre simultané, en privilégiant des algorithmes à profondeur d'abord qui sont généralement moins gourmand en appels récursifs que les algorithmes en largeur d'abord.
newkam2013
Messages postés4Date d'inscriptionmercredi 21 août 2013StatutMembreDernière intervention22 août 2013 21 août 2013 à 21:57
Je te remercie beaucoup pour ton message! les fonctions sont réellement très simples, ( pour ne pas encombrer le main). si j'ai bien compris ta proposition, il vaut mieux développer ces fonctions à l'intérieur du main? J'ai passé la journée entière à essayer de trouver une façon pour résoudre ce problème, il faut avouer que je suis redevenu un débutant en programmation. Je te remercie encore!
KX
Messages postés16734Date d'inscriptionsamedi 31 mai 2008StatutModérateurDernière intervention24 avril 2024127 21 août 2013 à 22:36
Je ne dis pas tout mettre dans le main, mais éviter d'avoir des fonctions récursives.
En effet à chaque fois qu'une fonction X appelle une fonction Y, l'exécution de X est mis en pause et stockée dans la pile d'appel en attendant que la fonction Y soit terminée. Avec les appels récursifs on se retrouve avec X qui appelle X qui appelle X, etc. le nombre de méthodes ouvertes en même temps devient donc très important, jusqu'à dépasser la taille de stockage de la pile.
Ce qu'il faut faire c'est diminuer le nombre de fonctions ouvertes en même temps afin de rester dans la limite de la pile.
Cela se fait en changeant d'algorithme, passer du récursif à l'itératif, du parcours en largeurs à un parcours en profondeur, ou encore en faisant de la récursivité terminale (faire en sorte que la fonction X n'est plus rien à faire après la fin de Y, comme ça le compilateur peut optimiser le traitement en fermant X avant d'ouvrir Y, ce qui évite de mettre X dans la pile)
Exemple simple, la fonction factorielle.
// récursive
int fac1(int n)
{
if (n>1)
return fac1(n-1)*n;
else
return 1;
}
// récursive terminale
int fac2(int n)
{
return fac2(n,1);
}
int fac2(int n, int r)
{
if (n>1)
return fac2(n-1,r*n);
else
return r;
}
// itérative
int fac3(int n)
{
int r=1;
for (int i=2; i<=n; i++)
r *= i;
return i;
}
newkam2013
Messages postés4Date d'inscriptionmercredi 21 août 2013StatutMembreDernière intervention22 août 2013 21 août 2013 à 22:49
Je comprends mieux la, je te remercie pour tes explications, et pour le temps que tu as consacré à me répondre, je vais essayer d'appliquer ce que tu m'as conseillé et utiliser aussi les std::vector, et je te tienderais au courant!
Merci encore!
Vous n’avez pas trouvé la réponse que vous recherchez ?
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023123 22 août 2013 à 11:04
Bonjour.
En plus de vérifier si tu as des fonctions récursives non terminales, je t'invite aussi à vérifier que tes tableaux statiques ne soient pas trop gros. Autant des tableaux "alloués en mémoire" (pour vulgariser) n'ont pas de limite de taille autre que la RAM, autant des tableaux "alloués" sur la pile, ont une limite basse.
Si tu fais du C++, il est évident que tu devrais utiliser les outils fournis avec ce langage, notamment le std::vector.
Quelques petites trucs qui me choquent dans ton code:
- Évite les using namespace, voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace
- Découpe ton code en petites fonctions ! Une fonction proprement écrite dépasse rarement 50 lignes. Chaque étape logique devrait être une fonction.
- std::ostream + std::ios::in => std::ifstream, donc pas besoin de remettre std::ios::in en argument des std::ifstream. Même remarque pour les std::ofstream
- Pas besoin de "fichier.close()", c'est automatique à la destruction de l'objet "fichier" (au sortir du scope).
- Évite les variables globales. Un code propre n'en a pas. (Variables globales != constantes globales, les constantes étant tout à fait acceptable).
- Si tu as accès au C++0x (option std=C++0x), alors tu peux avantageusement remplacer le rand/srand par un mersenne_twister, bien plus efficace, et qui t'affranchie d'utiliser du C.