C++ : problème de tableau dynamique dans une classe

Résolu
rollingsteen Messages postés 5 Date d'inscription vendredi 27 novembre 2009 Statut Membre Dernière intervention 28 novembre 2009 - 27 nov. 2009 à 18:40
rollingsteen Messages postés 5 Date d'inscription vendredi 27 novembre 2009 Statut Membre Dernière intervention 28 novembre 2009 - 28 nov. 2009 à 01:59
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

cs_juju12 Messages postés 966 Date d'inscription samedi 3 avril 2004 Statut Membre Dernière intervention 4 mars 2010 4
27 nov. 2009 à 20:23
Je te suggère d'enlever la ligne
delete[] this->digits;
dans le constructeur BigInt, car c'est absurde.
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
27 nov. 2009 à 20:25
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.
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
27 nov. 2009 à 20:27
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 ;)
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
27 nov. 2009 à 20:33
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.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
rollingsteen Messages postés 5 Date d'inscription vendredi 27 novembre 2009 Statut Membre Dernière intervention 28 novembre 2009
28 nov. 2009 à 01:21
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++?
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
28 nov. 2009 à 01:26
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.
0
rollingsteen Messages postés 5 Date d'inscription vendredi 27 novembre 2009 Statut Membre Dernière intervention 28 novembre 2009
28 nov. 2009 à 01:36
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.
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
28 nov. 2009 à 01:43
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)
0
rollingsteen Messages postés 5 Date d'inscription vendredi 27 novembre 2009 Statut Membre Dernière intervention 28 novembre 2009
28 nov. 2009 à 01:53
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)
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
28 nov. 2009 à 01:57
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à.
0
rollingsteen Messages postés 5 Date d'inscription vendredi 27 novembre 2009 Statut Membre Dernière intervention 28 novembre 2009
28 nov. 2009 à 01:59
mais en tout cas merci pour les conseils, j'en attendait pas tant et surtout pas aussi rapidement!
0
Rejoignez-nous