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 :

Access Violation sur un delete


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    lkjlgj
    Inscrit en
    Février 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : Angola

    Informations professionnelles :
    Activité : lkjlgj

    Informations forums :
    Inscription : Février 2007
    Messages : 255
    Par défaut Access Violation sur un delete
    Bonjour,

    Je cherche à comprendre pourquoi un delete qui porte sur un tableau de longs de taille définie et invariable plante alors que je peux jusqu'à ce point effectuer toutes les opérations de lecture et écriture dans ce tableau sans le moindre problème.

    Sans m'étendre sur les détails, voici une idée du code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    long *Tablo = new long [100];
     
    for(long i=0; i<100; i++) Tablo[i]=i;
     
    if(Tablo)	
    {
    delete[] Tablo;    // Et là, ça plante : "Access Violation"
    Tablo=NULL;
    }

  2. #2
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Est-ce que ce code plante? Je ne pense pas.

    Que l'équivalent de ce code, noyé au milieu de plusieurs milliers d'autres lignes plante, c'est possible.

    Il suffit simplement qu'il y ait un buffer overflow quelque part ou que Tablo ait été modifié par erreur (Tablo++), et voila...

    Connais-tu std::vector?
    http://cpp.developpez.com/faq/cpp/?page=STL#STL_vector

  3. #3
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    En C++, on a maintenant des outils pour déléguer la gestion pure de la mémoire à des entités (classes en fait). Ca s'appelle le RAII.
    Les tableaux sont dans 99% des cas remplacer par un vector (cf remarque d'Aurélien). Les 1% restant, on utilise boost::array.
    En ce qui concerne les pointeurs, on a aussi tout intérêt à les "donner" à une classe qui les gère, comme boost::shared_ptr.

  4. #4
    Membre éclairé
    Profil pro
    lkjlgj
    Inscrit en
    Février 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : Angola

    Informations professionnelles :
    Activité : lkjlgj

    Informations forums :
    Inscription : Février 2007
    Messages : 255
    Par défaut
    Ouais...

    Devant mon impossibilité de trouver pourquoi le delete plante, j'avais déjà pensé à vector que j'utilise un peu (dans d'autres programmes).
    C'est juste que ça me turlupine de pas comprendre pourquoi le delete plante alors que je peux je lire / écrire partout dans cette zone mémoire apparemment bien délimitée. Si moi et l'ordinateur on est d'accord sur l'attribution des 100 cases depuis le début, alors pourquoi le delete (qui doit avoir gardé trace du new long [100]) ne marche-t-il-pas ?

    Je crois comprendre la théorie du Tablo++ fautif, mais en vérifiant l'adresse de Tablo, au début et à la fin du programme, je constate qu'elle est la même, donc il n'y a pas eu de déplacement erroné de Tablo. Alors quele peut être la cause du problème ?

    En tout état de cause, je passe à Vector...

  5. #5
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Y'a une explication, mais le code que nous montre est correct. Peut-être qu'avec un peu plus de code on verrait d'où vient le problème...

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    On peut fortement envisager le fait qu'il y ait quelque chose entre la partie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(long i=0; i<100; i++) Tablo[i]=i;
    et la partie
    Et il y a fort à parier (bien que n'ayant pas vu le code) qu'il y aura l'un ou l'autre appel de fonction

    Si l'une de ces fonctions appelées (ou pire, l'une des fonctions éventuellement appelées par une des fonctions qui se trouve entre les deux parties de code) appelle delete[] sur Tablo (ou sur le nom qu'il obtient lors du passage par argument), bien que *sensé* représenter une adresse valide, ce n'est peut être plus le cas.

    A ce moment là, toute tentative de refaire un delete[] sur cette adresse - devenue invalide - occasionnera systématiquement une violation d'accès

    Si donc, tu as d'autres fonctions qui peuvent vouloir libérer la mémoire de ce pointeur, il est préférable de fournir un pointeur de pointeur comme argument, de libérer la mémoire sur ce qui est pointé par cet argument et de le faire pointer sur NULL.

    Cela permettra, au sortir de la fonction, que Tablo valle NULL et donc que le test ne provoque pas cette tentative de nouvelle libération de la mémoire

    Ceci dit, on ne peut que t'inciter à envisager l'utilisation des std::vector<un type> aussi souvent que possible
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Access violation sur une string
    Par Nekkro dans le forum C++
    Réponses: 11
    Dernier message: 23/01/2012, 08h41
  2. Access violation sur dsnap140.bpl
    Par Ben_Le_Cool dans le forum Langage
    Réponses: 4
    Dernier message: 29/07/2011, 20h06
  3. Réponses: 5
    Dernier message: 27/01/2009, 10h58
  4. Access violation sur un new
    Par cedekasme dans le forum C++Builder
    Réponses: 16
    Dernier message: 23/01/2007, 14h32
  5. Réponses: 7
    Dernier message: 23/05/2006, 11h32

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