2009-07-07 6 views
2

J'ai eu erreur de violation d'accès lorsque le code suivant est exécuter:Tableau de pointeurs de fonction membre: Obtenir 0xcccccccc lorsque le contrôle a atteint pointeur vers une fonction membre

void NoAction() 
{ 
    (*m_psStateMachine[0][0])(); 
} 
class CXcp 
{ 
public: 
    CXcp(){} 
    CXcp(WORD wXcpProtocol); 
    ~CXcp(); 

private: 
    void (*m_psStateMachine[10][16])(); 

public:  
    // Action Methods from State M/c Table in the RFC//  
    void IrcScr_6(){} 
    void IrcStr_4(){} 
    void TldIrcStr_4(){} 
    void Tls_1(){} 
    void Tld_1(){} 
    void Tlf_0(){} 
    void Tld(){} 
    void Str_4(){} 
    void Str_5(){} 
    void Scr_6(){} 
    void Scr_8(){} 
    void Tlf_2(){} 
    void Tlf_3(){} 
    void Tlf_3p(){} 
    void Sta_2(){} 
    void IrcScrSca_8(){} 
    void Sca_8(){} 
    void ScaTlu_9(){} 
    void TldScrSca_8(){} 
    void Scn_6(){} 
    void Scn_7(){} 
    void TldScrScn_6(){} 
    void IrcScrScn_8(){} 
    void Irc_7(){} 
    void Scr_6x(){} 
    void IrcTlu_9(){} 
    void TldScr_6x(){} 
    void Sta_3(){} 
    void IrcScr_8(){} 
    void Sta_4(){} 
    void Sta_5(){} 
    void Sta_6(){} 
    void TldZrcSta_6(){} 
    void TldScr_6(){} 
    void Scj_2(){} 
    void Scj_3(){} 
    void Scj_4(){} 
    void Scj_5(){} 
    void Scj_6(){} 
    void Scj_7(){} 
    void Scj_8(){} 
    void Scj_9(){} 
    void TldIrcStr_5(){} 
    void Ser_9(){} 

    void NoAction() 
    { 
     (*m_psStateMachine[0][0])(); 
    } 
    void Initial() {} 
    void Starting() {} 
    void Closed() {} 
    void Stopped() {} 
    void Closing() {} 
    void Stopping() {} 
    void ReqSent() {} 
    void AckRecvd() {} 
    void AckSent() {} 
    void Opened() {} 
}; 

CXcp::CXcp(WORD wXcpProtocol) 
{ 


// Kernel of the PPP the State M/c : Initialization Here 
    void (CXcp :: *m_psStateMachine[10][16])() = 
    { 
/*   State          
      0   1    2   3   4   5   6   7   8   9   
Events | INITIAL STARTING  CLOSED  STOPPED CLOSING STOPPING Req-Sent Ack-Rcvd Ack-Sent OPENED */ 

/*Up*/  &CXcp::Initial, &CXcp::IrcScr_6, &CXcp::NoAction, &CXcp::NoAction, &CXcp::NoAction, &CXcp::NoAction, &CXcp::NoAction, &CXcp::NoAction, &CXcp::NoAction, &CXcp::NoAction, 

/*Down*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::Initial, &CXcp::Tls_1, &CXcp::Initial, &CXcp::Starting, &CXcp::Starting, &CXcp::Starting, &CXcp::Starting, &CXcp::Tld_1, 

/*Open*/ &CXcp::Tls_1, &CXcp::Starting, &CXcp::IrcScr_6, &CXcp::NoAction, &CXcp::NoAction, &CXcp::NoAction, &CXcp::ReqSent, &CXcp::AckRecvd, &CXcp::AckSent, &CXcp::Opened, 

/*Close*/ &CXcp::Initial, &CXcp::Tlf_0, &CXcp::Closed, &CXcp::Closed, &CXcp::Closing, &CXcp::Closing, &CXcp::IrcStr_4, &CXcp::IrcStr_4, &CXcp::IrcStr_4, &CXcp::TldIrcStr_4, 

/*TO+*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::NoAction, &CXcp::NoAction, &CXcp::Str_4, &CXcp::Str_5, &CXcp::Scr_6, &CXcp::Scr_6, &CXcp::Scr_8, &CXcp::NoAction, 

/*TO-*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::NoAction, &CXcp::NoAction, &CXcp::Tlf_2, &CXcp::Tlf_3, &CXcp::Tlf_3p, &CXcp::Tlf_3p, &CXcp::Tlf_3p, &CXcp::NoAction, 

/*RCR+*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::Sta_2, &CXcp::IrcScrSca_8, &CXcp::Closing, &CXcp::Stopping, &CXcp::Sca_8, &CXcp::ScaTlu_9, &CXcp::Sca_8, &CXcp::TldScrSca_8, 

/*RCR-*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::Sta_2, &CXcp::IrcScrSca_8, &CXcp::Closing, &CXcp::Stopping, &CXcp::Scn_6, &CXcp::Scn_7, &CXcp::Scn_6, &CXcp::TldScrScn_6, 

/*RCA*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::Sta_2, &CXcp::IrcScrScn_8, &CXcp::Closing, &CXcp::Stopping, &CXcp::Irc_7, &CXcp::Scr_6x, &CXcp::IrcTlu_9, &CXcp::TldScr_6x, 

/*RCN*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::Sta_2, &CXcp::Sta_3, &CXcp::Closing, &CXcp::Stopping, &CXcp::IrcScr_6, &CXcp::Scr_6x, &CXcp::IrcScr_8, &CXcp::TldScr_6x, 

/*RTR*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::Sta_2, &CXcp::Sta_3, &CXcp::Sta_4, &CXcp::Sta_5, &CXcp::Sta_6, &CXcp::Sta_6, &CXcp::Sta_6, &CXcp::TldZrcSta_6, 

/*RTA*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::Closed, &CXcp::Stopped, &CXcp::Tlf_2, &CXcp::Tlf_3, &CXcp::ReqSent, &CXcp::ReqSent, &CXcp::AckSent, &CXcp::TldScr_6, 

/*RUC*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::Scj_2, &CXcp::Scj_3, &CXcp::Scj_4, &CXcp::Scj_5, &CXcp::Scj_6, &CXcp::Scj_7, &CXcp::Scj_8, &CXcp::Scj_9, 

/*RXJ+*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::Closed, &CXcp::Stopped, &CXcp::Closing, &CXcp::Stopping, &CXcp::ReqSent, &CXcp::ReqSent, &CXcp::AckSent, &CXcp::Opened, 

/*RXJ-*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::Tlf_2, &CXcp::Tlf_3, &CXcp::Tlf_2, &CXcp::Tlf_3, &CXcp::Tlf_3, &CXcp::Tlf_3, &CXcp::Tlf_3, &CXcp::TldIrcStr_5, 

/*RXR*/ &CXcp::NoAction, &CXcp::NoAction, &CXcp::Closed, &CXcp::Stopped, &CXcp::Closing, &CXcp::Stopping, &CXcp::ReqSent, &CXcp::AckRecvd, &CXcp::AckSent, &CXcp::Ser_9 

    }; 
} 

CXcp::~CXcp() 
{ 

} 

int main(void) 
{ 
    CXcp oXcp(10); 
    oXcp.NoAction(); 
    return 0; 
} 

réponse sera très appréciée.

Merci à l'avance

+0

Modifier votre question d'inclure le code correspondant. –

Répondre

3

Eh bien, vous n'initialisent pas ce membre:

void (*m_psStateMachine[10][16])(); 

Qu'est-ce que vous faites est à la place créer un tableau local à l'intérieur du constructeur, et initialisez que. Cela ne peut qu'échouer. Changer le membre à ce

void (CXcp::*m_psStateMachine[10][16])(); 

Et dans le constructeur, copiez votre tableau local dans l'élément (et mieux supprimer le préfixe m_ du nom du tableau local, il est donc ne pas confondre avec le tableau de membre effectif).

for(int i = 0; i < 10; i++) 
    for(int j = 0; j < 16; j++) 
    this->m_psStateMachine[i][j] = stateMachine[i][j]; 

Vous pouvez attribuer à chaque élément séparément, si vous aimez d'énormes douleurs :) Ensuite, vous appelez le tableau de pointeurs membres en utilisant une autre syntaxe

(this->*m_psStateMachine[0][0])(); 

Bien sûr, quelque part vous devez dites-le sur quel objet il est appelé.

+0

Merde :) Bien sûr, une copie (m_psStateMachine, ....); ne fonctionne pas avec un tableau multidimensionnel :) Corrigé. –

+1

Mieux vaut ne pas utiliser le préfixe m_ member sur une variable locale - c'est ce genre de confusion qui a conduit au problème en premier lieu. L'utilisation d'un préfixe m_ pour un local devrait être un avertissement du compilateur pour cette raison. – MSalters

+0

Vous avez raison. je vais l'enlever –

1

Il y a un certain nombre de bugs dans ce code:

  1. Le code tente de pointeurs de méthodes de stockage dans m_psStateMachine, qui est déclaré comme « tableau de tableau de pointeur de fonction renvoyant void »:

    privé: void (* m_psStateMachine [10] [16])();

  2. Plus tard, vous créez une variable locale/statique avec des pointeurs de méthode:

    void (CXcp :: *m_psStateMachine[10][16])() = ...
    Cela n'a aucun effet sur la m_psStateMachine visible à l'intérieur de vos méthodes, vous auriez à échapper à l'accès à l'aide ::m_psStateMachine. Lorsque vous appelez des méthodes via le tableau de pointeurs de méthode, vous devez indiquer au compilateur quelle valeur utiliser pour this, comme dans (this->*m_psStateMachine[0][0])().

Je vous suggère de remplacer la déclaration du tableau de pointeur de méthode avec quelque chose le long des lignes de

class ... { 
    static const void (CXcp::*m_psStateMachine[10][16])(); 
    ... 
}; 
const void (CXcp::*CXcp::m_psStateMachine[10][16])() = { ... }; 
Questions connexes