2012-12-22 2 views
4

Quel est le problème avec ce code ci-dessous et comment y remédier.exception: violation d'accès

#include<iostream> 
using namespace std; 

template<typename Func1, typename Func2> 
class guard{ 
public: 
    guard(Func1 first, Func2 last) : last(last){ 
     first(); 
    } 
    ~guard(){ 
     last(); 
    } 
private: 
    Func2& last; 
}; 

template<typename Func1, typename Func2> 
guard<Func1, Func2> make_guard(Func1 first, Func2 last){ 
    return guard<Func1, Func2>(first, last); 
} 

void first(){ 
    cout << "first" << endl; 
} 

void last(){ 
    cout << "last" << endl; 
} 

int main(){ 
    { 
     first(); // ok 
     last(); // ok 
     auto g = make_guard(first, last); 
     first(); //exception: Access violation 
     last(); //exception: Access violation 
    } 
    first(); // ok 
    last(); // ok 
    cin.get(); 
} 

La fonction first() et last() ne peut pas être appelée avant la variable g a expiré. Compilé à VC++ 2012 et a le même problème à la fois en mode de débogage et de publication.

Répondre

5

Votre guard conserve une référence , mais il prend une valeur . La référence devient invalide dès la fin du constructeur de guard, car elle fait référence au paramètre last pris par le constructeur et non au paramètre passé à make_guard.

Lorsque vous accédez à une référence invalide, vous avez le comportement non défini, et tous les paris sont désactivés.

+0

Merci. déjà le réparer. Mais je ne comprends toujours pas pourquoi la fonction d'appel 'first()' et 'last()' a échoué directement quand la variable 'g' n'est pas expirée. –

+1

@Mike: Une fois que vous êtes impliqué dans un comportement indéfini, tout peut arriver ... –

+0

Les adresses globales ne sont-elles pas les premières et les dernières? Pourquoi deviennent-ils invalides? – user93353

Questions connexes