tags:

views:

526

answers:

2

Hi,

I got error Access Violation when the following code is execute :

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;
}

Answer will be highly appreciated.

Thanks in advance

+3  A: 

Well, you don't initialize this member:

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

What you do instead is creating a local array inside the constructor, and initialize that. That can only fail. Change the member to this

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

And in the constructor, copy your local array into the member (and better remove the m_ prefix from the local array's name, so it's not confused with the actual member array).

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

Alternatively, you can assign each element separately, if you like huge pains :) Then you call the array of member pointers using another syntax

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

Of course, somewhere you need to tell it on which object it's invoked on.

Johannes Schaub - litb
Crap :) Of course, a copy(m_psStateMachine, ....); doesn't work with a multi dimensional array :) Corrected.
Johannes Schaub - litb
Better not use the m_ member prefix on a local variable - it's that kind of confusion that lead to the problem in the first place. Using an m_ prefix for a local should be a compiler warning for this reason.
MSalters
You are right. i'll remove it
Johannes Schaub - litb
+1  A: 

There are a number of bugs in that code:

  1. The code is trying to store method pointers into m_psStateMachine, which is declared as "array of array of pointer to function returning void":

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

  2. Later you create a local/static variable with method pointers:

    void (CXcp :: *m_psStateMachine[10][16])() = ...
    This will have no effect on the m_psStateMachine visible inside your methods, you'd have to escape access using ::m_psStateMachine.

  3. When calling methods via the method pointer array, you'll have to tell the compiler which value to use for this, like in (this->*m_psStateMachine[0][0])().

I'd suggest to replace the declaration of the method pointer array with something along the lines of

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