IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Problème en mémoire avec des tableaux


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    53
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 53
    Points : 26
    Points
    26
    Par défaut Problème en mémoire avec des tableaux
    Bonjour,

    J'ai le programme suivant (implémentation d'un stack) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    #include <stdlib.h>
     
    #include <iostream>
     
    #include <string>
     
     
    using namespace std;
     
     
    int nb = 0; // number of elements
    int k = 2; // maximum number of elements
     
    int *table; // point to the main table
     
    // init hte stack
    void init()
    {
    table = new int[2];
    k=2;
    nb = 0;
    }
     
    // take an element
    int pop()
    {
    // if stack is empty
    if (nb == 0) {
    cout << "stack is empty" << endl;
    return -1;
    }
    nb--;
    return table[nb];
    }
     
    // write an element in the stack
    void push(int element)
    {
    // if the table can't accept the new element
    if ((nb + 1) > k) {
    int *p; // new pointer for the new table
    k = 2 * k;
    p = new int[k];
     
    // copy the content to the new table
    int i;
    for (i = 0; i < nb; i++) {
    p[i] = table[i];
    }
    // delete the old table
    delete[] table;
    // change the pointer
    table = p;
    }
    // write the element
    table[nb] = element;
    nb++;
    }
     
    // return the size of the stack
    int size()
    {
    return nb;
    }
     
    // kill the table in memory
    void clear()
    {
    delete[] table;
    nb=0;
    }
     
     
     
     
    // test function
     
    int test()
    {
    cout << "The program has been startet without any arguments." << endl;
    cout << "The program enters the stack test mode:" << endl;
    cout << "Enter one of the commands: push, pop, end" << endl;
     
    string command;
     
     
    do {
    cin >> command;
    if (command == "pop") {
    cout << pop() << endl;
    } else if (command == "push") {
    cout << "element?";
    int elementToPush;
    cin >> elementToPush;
    push(elementToPush);
    } else if (command == "end") {
    clear();
    } else {
    cout << "command not recognised" << endl;
    };
    }
    while (command != "end");
    return 0;
    }
     
     
    int main(int argc, char *argv[])
    {
    init();
    test();
    clear();
    return 0;
    }
    J'obtiens le résultat suivant (qui est correct) masi avec un message d'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    The program has been startet without any arguments.
    The program enters the stack test mode:
    Enter one of the commands: push, pop, end
    push
    element?4
    push
    element?1
    pop
    1
    push
    element?5
    push
    element?9
    pop
    9
    pop
    5
    pop
    4
    pop
    stack is empty
    -1
    end
     
    *** glibc detected *** ./array: double free or corruption (fasttop): 0x0804b008 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6[0xb7d2dd65]
    /lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7d31800]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7ef6d81]
    /usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xb7ef6ddd]
    ./array(__gxx_personality_v0+0x1ae)[0x8048a32]
    ./array[0x8048cf4]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7cda050]
    ./array(__gxx_personality_v0+0x4d)[0x80488d1]
    ======= Memory map: ========
    08048000-0804a000 r-xp 00000000 08:03 1126215 /home/tguillod/eth/info/ubung/u6/array
    0804a000-0804b000 rw-p 00001000 08:03 1126215 /home/tguillod/eth/info/ubung/u6/array
    0804b000-0806c000 rw-p 0804b000 00:00 0 [heap]
    b7b00000-b7b21000 rw-p b7b00000 00:00 0
    b7b21000-b7c00000 ---p b7b21000 00:00 0
    b7cc3000-b7cc4000 rw-p b7cc3000 00:00 0
    b7cc4000-b7e08000 r-xp 00000000 08:03 476707 /lib/tls/i686/cmov/libc-2.6.1.so
    b7e08000-b7e09000 r--p 00143000 08:03 476707 /lib/tls/i686/cmov/libc-2.6.1.so
    b7e09000-b7e0b000 rw-p 00144000 08:03 476707 /lib/tls/i686/cmov/libc-2.6.1.so
    b7e0b000-b7e0e000 rw-p b7e0b000 00:00 0
    b7e0e000-b7e18000 r-xp 00000000 08:03 473347 /lib/libgcc_s.so.1
    b7e18000-b7e19000 rw-p 0000a000 08:03 473347 /lib/libgcc_s.so.1
    b7e19000-b7e1a000 rw-p b7e19000 00:00 0
    b7e1a000-b7e3d000 r-xp 00000000 08:03 476715 /lib/tls/i686/cmov/libm-2.6.1.so
    b7e3d000-b7e3f000 rw-p 00023000 08:03 476715 /lib/tls/i686/cmov/libm-2.6.1.so
    b7e3f000-b7f27000 r-xp 00000000 08:03 230797 /usr/lib/libstdc++.so.6.0.9
    b7f27000-b7f2a000 r--p 000e8000 08:03 230797 /usr/lib/libstdc++.so.6.0.9
    b7f2a000-b7f2c000 rw-p 000eb000 08:03 230797 /usr/lib/libstdc++.so.6.0.9
    b7f2c000-b7f32000 rw-p b7f2c000 00:00 0
    b7f47000-b7f4b000 rw-p b7f47000 00:00 0
    b7f4b000-b7f65000 r-xp 00000000 08:03 473300 /lib/ld-2.6.1.so
    b7f65000-b7f67000 rw-p 00019000 08:03 473300 /lib/ld-2.6.1.so
    bfc3c000-bfc52000 rw-p bfc3c000 00:00 0 [stack]
    ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]
    Aborted (core dumped)

    C'est un problème de libération de mémoire (fonction clear()). Mais je n'arrive pas le trouver.
    Quelqu'un peut il m'aider ?

  2. #2
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    en fait tu libères deux fois le même pointeur. Tu fais un clear à la fin de ta fonction test, et un dans ton main.

    Soit tu en enlèves un, soit tu modifies ta fonction clear:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    // kill the table in memory
    void clear()
    {
        delete[] table, table = NULL;
        nb=0;
    }

  3. #3
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    53
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 53
    Points : 26
    Points
    26
    Par défaut
    Pour moi je ne libère pas deux fois la même chose. En effet après avoir libérer le pointeur dans la fonction push() je change sa valeur.
    Le pointeur pointe donc sur le tableau p.
    La solution que tu m'as proposé marche mais j'aimerai comprendre pourquoi !

  4. #4
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    ca je suis d'accord, il n'y a pas de problème dans la fonction push.

    Maintenant regarde ce qui se passe dans la fonction test quand tu tapes 'end': la fonction test fais un appel à clear(). Ensuite, quand tu regardes dans le main, après la fonction test tu as un deuxième appel à clear().

    Ca se voit mieux si tu met directement le contenu de test() dans le main:

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    #include <cstdlib>
     
    #include <iostream>
     
    #include <string>
     
     
    using namespace std;
     
     
    int nb = 0; // number of elements
    int k = 2; // maximum number of elements
     
    int *table; // point to the main table
     
    // init hte stack
    void init()
    {
    table = new int[2];
    k=2;
    nb = 0;
    }
     
    // take an element
    int pop()
    {
    // if stack is empty
    if (nb == 0) {
    cout << "stack is empty" << endl;
    return -1;
    }
    nb--;
    return table[nb];
    }
     
    // write an element in the stack
    void push(int element)
    {
    // if the table can't accept the new element
    if ((nb + 1) > k) {
    int *p; // new pointer for the new table
    k = 2 * k;
    p = new int[k];
     
    // copy the content to the new table
    int i;
    for (i = 0; i < nb; i++) {
    p[i] = table[i];
    }
    // delete the old table
    delete[] table;
    // change the pointer
    table = p;
    }
    // write the element
    table[nb] = element;
    nb++;
    }
     
    // return the size of the stack
    int size()
    {
    return nb;
    }
     
    // kill the table in memory
    void clear()
    {
    delete[] table;
    nb=0;
    }
     
     
    int main(int argc, char *argv[])
    {
    init();
    
    cout << "The program has been startet without any arguments." << endl;
    cout << "The program enters the stack test mode:" << endl;
    cout << "Enter one of the commands: push, pop, end" << endl;
     
    string command;
     
     
    do {
    cin >> command;
    if (command == "pop") {
    cout << pop() << endl;
    } else if (command == "push") {
    cout << "element?";
    int elementToPush;
    cin >> elementToPush;
    push(elementToPush);
    } else if (command == "end") {
    clear();
    } else {
    cout << "command not recognised" << endl;
    };
    }
    while (command != "end");
    
    clear();
    return 0;
    }

    Tu vois bien les deux clear() d'affilée

Discussions similaires

  1. Problème de mémoire avec des Bitmap
    Par Ryu2000 dans le forum Android
    Réponses: 11
    Dernier message: 06/04/2012, 11h34
  2. Problème de gcnew avec des tableaux
    Par tank86 dans le forum C++/CLI
    Réponses: 3
    Dernier message: 04/11/2010, 23h13
  3. Réponses: 11
    Dernier message: 16/07/2007, 16h33
  4. Réponses: 6
    Dernier message: 20/02/2007, 17h00
  5. [Tableaux] Problème de foreach avec des checkboxes
    Par nanor21 dans le forum Langage
    Réponses: 10
    Dernier message: 15/05/2006, 01h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo