2

多項式の演算を扱うプログラムがあります。「operator」クラスには、入力文字列への char ポインター、つまり引数に対して操作を実行するために使用されるタイプ float (float、float) の関数へのポインターがあります。その後、一連のメソッドがあり、setSymb(char *) は opChar を引数にポイントし、opFunc ポインタを演算子文字に対応する関数にポイントします。ただし、このメソッドを実行すると、関数をポインター関数に割り当てる行で、何らかのメモリを割り当てようとすると、new.cpp の下に未処理の例外が発生します。これは私を大いに混乱させます。

#include "stckArrClassLib.h"
using namespace stacks;
using namespace conversion;

#define SIDE bool
#define LEFT 0
#define RIGHT 1

class oprt
{
public:
    typedef float (oprt::*fp)(float, float);
private:
    char *opSymb;
    fp opFunc;
    float *lOpnd;
    float *rOpnd;
    oprt *Lnext;
    oprt *Rnext;
    float rslt;
protected:
        float add(float a, float b){return a+b;};
    float mult(float a, float b){return a*b;};
    float div(float a, float b){return a/b;};
    float exp(float a, float b){return powf(a, b);};
    float par(float a, float b){return a;};
public:
    oprt (void) {opFunc=NULL;};
    oprt &setSymb(char *);
    oprt &setNext(SIDE, oprt *);
    oprt &setOpnd(SIDE, float);
    float evaluate();
    char *getSymb();
    fp getFunc();
    float *getOpnd(SIDE);
    oprt *getNext(SIDE);
};

oprt& oprt::setSymb(char *set)
{
        CArray<char, 8> opStr;
    opStr[0]=*(set), set;
    int i;
    for(i=1; i<7 && (!(set[i]>='0' && set[i]<='9') && !(set[i]=='+' || set[i]=='-' || opStr[i]=='*' || set[i]=='/' || set[i]=='^' || set[i]=='(')); i++)
    opStr[i]=set[i];
    opStr[i]=0;
    if(strcmp((const char *)opStr.arr, "+")==0)
            //problem is here
    opFunc=&oprt::add;
    else if(strcmp((const char *)opStr.arr, "*")==0)
            //and here
    opFunc=&oprt::mult;
    else if(strcmp((const char *)opStr.arr, "/")==0)
            //etc.
    opFunc=&oprt::div;
    else if(strcmp((const char *)opStr.arr, "^")==0)
    opFunc=&oprt::exp;
    else if(strcmp((const char *)opStr.arr, "(")==0 || strcmp((const char *)opStr.arr, ")")==0)
    opFunc=&oprt::par;
        return *this;
}

oprt& oprt::setNext(SIDE side, oprt *next)
{
    if(side==LEFT)
{
    Lnext=next;
    lOpnd=&(next->rslt);
}
else if(side==RIGHT)
{
    Rnext=next;
    rOpnd=&(next->rslt);
}
return *this;
}

float oprt::evaluate()
{
return rslt=(this->*opFunc)(*getOpnd(LEFT), *getOpnd(RIGHT));
}

char *oprt::getSymb()
{
return opSymb;
}

oprt::fp oprt::getFunc()
{
return opFunc;
}

float *oprt::getOpnd(SIDE side)
{
if(!((side==LEFT)? (Lnext==this):(Rnext==this)))
    (side==LEFT? Lnext:Rnext)->evaluate();
return (side==LEFT)? (lOpnd):(rOpnd);
}

oprt *oprt::getNext(SIDE side)
{
return (side==LEFT)? (Lnext):(Rnext);
}

oprt& oprt::setOpnd(SIDE side, float set)
{
(side==LEFT)? (*lOpnd=set):(*rOpnd=set);
return *this;
}

opFunc=&oprt::add関数内で呼び出される new.cpp の抜粋を次に示します。oprt& oprt::setSymb(char *)

extern "C" void * __cdecl _nh_malloc_dbg (
    size_t nSize,
    int nhFlag,
    int nBlockUse,
    const char * szFileName,
    int nLine
    )
{
    int errno_tmp = 0;
    void * pvBlk = _nh_malloc_dbg_impl(nSize, nhFlag, nBlockUse, szFileName, nLine, &errno_tmp);

    if ( pvBlk == NULL && errno_tmp != 0 && _errno())
    {
        errno = errno_tmp; // recall, #define errno *_errno()
    }
    return pvBlk;
}

エラーは、malloc が呼び出されたときに呼び出されます。

4

1 に答える 1

1

typedef を次のように変更する必要があると思います。

typedef float (oprt::*fp)(float, float);

また、割り当て時に「&」アンパサンドを省略したくありません。

opFunc=&oprt::mult;
于 2012-10-11T01:33:39.517 に答える