C++ : problème de tableau dynamique dans une classe [Résolu]

Signaler
Messages postés
5
Date d'inscription
vendredi 27 novembre 2009
Statut
Membre
Dernière intervention
28 novembre 2009
-
Messages postés
5
Date d'inscription
vendredi 27 novembre 2009
Statut
Membre
Dernière intervention
28 novembre 2009
-
Hello, je dois développer une application permettant de travailler sur de très gros nombres (200 digits) -> les digits sont stockés dans un tableau.

j'ai systématiquement une erreur de type "segmentation fault" à la fin du programme (les valeurs se sont déjà affichées en console et tout et tout) visiblement je ferais un accès mémoire interdit en ligne 36 mais je ne comprend pas du tout!

ça fait un moment que je n'ai pas travaillé avec des objets en c++ donc je ne sais pas si c'est à ce niveau là que quelque chose m'échappe.

Si quelqu'un arrivait à me trouver la cause de ce débordement ça serait hyper cool parce que là je sèche à mort!

#include 

using namespace std;

class BigInt
{
    private :
    int* digits;
    int  nbDigits;

    public:
    BigInt(int*, int);
    ~BigInt();
    //BigInt operator+ (BigInt);
    void print();
};

BigInt::BigInt(int* digits, int nbDigits)
{
    this->nbDigits = nbDigits;

    this->digits = new int[nbDigits];

    if(this->digits == NULL)
    {
        printf("L'allocation n'a pu etre realisee\n");
    }
    else
    {
        printf("L'allocation a ete un succes\n");
        delete[] this->digits;
    }

    for (int i=0; i<nbDigits; ++i)
    {
        this->digits[i] = digits[i]; // <--------------------------------------------- cette ligne!
    }
}

BigInt::~BigInt()
{
    delete[] this->digits;
    cout << "objet detruit";
}

void BigInt::print()
{
    for (int i=nbDigits-1; i>=0; --i)
    {
        printf("%i",digits[i]);
    }
}

int main()
{
    int t[6] = {1,2,3,4,5,6};
    BigInt i(t,6);
    i.print();
    return EXIT_SUCCESS;
}

11 réponses

Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
Je te suggère d'enlever la ligne
delete[] this->digits;
dans le constructeur BigInt, car c'est absurde.
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
C'est pas compliqué.

Tu assignes t à this->digits. Or, à la fin de la fonction, ton objet i de type BigInt est détruit. Le destructeur est donc appelé.

Dans ton destructeur, tu fais delete[] this->digits; Or this->digits équivaut à t, donc ça revient à faire delete[] t; Comme t est un tableau statique, tu essaies de libérer quelque chose de "readonly", et donc ça plante.
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
Oups pardon, j'ai lu un peu à la va vite. Ce que j'ai dit est faux puisque tu recopies bien "digits" en tant que nouveau tableau.
Toutes mes excuses.
Je vais jetter un "vrai" coup d'oeil ;)
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
Effectivement, juju12 a été plus attentif que moi, et c'est bien la cause de ton problème.
Pense aussi à utiliser std::cout et std::endl, plutôt que printf.
Messages postés
5
Date d'inscription
vendredi 27 novembre 2009
Statut
Membre
Dernière intervention
28 novembre 2009

merci juju12 effectivement c'est complètement absurde ce que j'ai fait, je ne sais pas pourquoi! (je crois qu'un peu de repos ne serait pas de trop haha) c'est fou le temps qu'on peut perdre pour ce genre de conneries auxquelles on ne fait plus attention par la suite :) du coup maintenant ça marche nickel, merci!

note: ah oui, je me rappelle d'où vient la faute... à la base j'avais fait un malloc et je ne me rappelais plus de l'utilisation donc go google, go wikipedia (http://fr.wikipedia.org/wiki/Malloc) et ils font un free pour une raison assez inconnue... du coup, le copier coller à la con sans analyser... l'erreur à la con quoi

CptPingu -> tu pense que utiliser la fonction cout est plus rapide que printf? bon, là elles y sont que pour du debug, ayant plus l'habitude des fonctions c, je me suis dit que de faire intervenir des "vieilles" fonctions seraient surement plus efficace, mais après j'en sais franchement pas plus.

en passant, est-ce qu'il y a un équivalent au realloc pour les tableaux en c++?
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
Si tu es en C++, tu codes en C++, pas en C. La rétro-compabilité ne veut pas dire mélanger des vieux trucs avec des nouveaux.
En C++, plutôt, que des tableaux, utilise la STL (list, vector, set ou map par exemple). Le redimensionnement est automatique, donc pas pas besoin d'utiliser directement realloc.
Messages postés
5
Date d'inscription
vendredi 27 novembre 2009
Statut
Membre
Dernière intervention
28 novembre 2009

le truc c'est que c'est pour faire des calculs relativement complexes pour des algorithmes de cryptage. donc dans un premier temps je vais devoir surcharger la plupart des opérateurs sur mon objet et le but c'est plutôt la rapidité et l'efficacité plutôt que la simplicité de codage, donc à priori plus j'utilise de fonction de "bas niveau" et plus ça sera efficace et léger, mais ça complique effectivement le codage. je pense que passer par ces objets serait quand même bien plus lourd. au fond, je fait en c++ juste pour avoir une notion d'objet pour mon type BigInt et pour simplifier mes boucles for :)

enfin, le cadre étant un cours de théorie de la complexité, il est plus facile d'évaluer la complexité et la place mémoire avec les "vieilles" fonctions :) après, je vais quand même checker pour ces objets que tu me propose, mais le prof n'en est pas fan. Mais c'est clair que si j'étais un peu plus libre, j'utiliserai directement une librairie permettant de traiter des très grand chiffres telle que GMP.
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
cryptage => chiffrement
librairie => bibliothèque

std::cout ne prends pas tellement plus de mémoire que printf. La plupart des objets du C++ sont faits à l'aide de méta-prog, qui remplace exactement par ce qu'il faut.
De plus, ce que tu vas optimiser n'est pas ceci. Si veux faire du chiffrement, tu ne vas t'amuser à faire de l'affichage de partout.

Enfin si tu veux des fonctions "bas niveau", printf ne l'est pas.
La fonction la plus basse que je connaisse pour l'affichage en C, est "write" (dans unistd.h)
Messages postés
5
Date d'inscription
vendredi 27 novembre 2009
Statut
Membre
Dernière intervention
28 novembre 2009

ouais, effectivement, comme j'ai dit, les printf actuels servent principalement à débugger, au final les fonctions les plus utilisées seront dédiées à l'allocation mémoire pour mes tableaux de chiffres, et en utilisant un type tel que vector, je ne suis plus vraiment certain de ce qui se passe au niveau de la mémoire.

enfin, le but étant surtout pédagogique, il faut que je fasse un programme pour lequel je puisse évaluer les ressources nécessaires à toutes les étapes. Du coup, je pense que je vais partir sur ma base actuelle maintenant qu'elle fonctionne. Par contre, j'écoute volontiers tes conseils au niveau optimisation s'il y en a. Mais le programme est vraiment axé algorithmie plutôt que codage à l'aide d'outils existant (et oui... comme toujours on réinvente la roue, mais c'est pas mal intéressant)
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
Dans ce cas, oui. Si c'est à but pédagogique, évite vector (qui est de toute façon pas aussi optimisé qu'un static_array qui n'est autre qu'un tableau).
Conserve donc du C pour tous ce qui est allocation, si ton but est vraiment celui-là.
Messages postés
5
Date d'inscription
vendredi 27 novembre 2009
Statut
Membre
Dernière intervention
28 novembre 2009

mais en tout cas merci pour les conseils, j'en attendait pas tant et surtout pas aussi rapidement!