環境:
ビジュアルスタジオ2008 sp1(c ++)
Windows 7 sp1 x64
win32 api+directxゲームプロジェクト
問題 :
//superclass of every variables.
//METHOD has automatically type-cast to int, float, string.
//and array function.
//this class series is using from script interpreter system.
class METHOD { // it is superclass of everything
friend class INTERPRETER;
protected:
BOOL constant;
//for variables & Functions
//TCHAR* m_name;
std::wstring m_name;
KEYWORD m_key;
RESERVED m_res;
int int_result;
std::wstring str_result;
float float_result;
TYPE m_type;
int m_level;
//tree
METHOD* root_ofme;
METHOD* sibling;
METHOD* left;
METHOD* right;
METHOD* parent;
//for FOR & BREAK class
//METHOD* m_targetToBreak;
BOOL m_breakingNow;
int m_rank; //priority
private:
public:
//constant
void EnableConstant(BOOL bcon);
void EnableConstant();
BOOL isConst();
//setter event
std::vector<METHOD*>* m_triggerTable;
std::vector<std::vector<METHOD*>*>* m_triggerArgs;
virtual void RunTrigger();
virtual void setTrigger(METHOD* mt, std::vector<METHOD*>* pVecArg);
virtual void removeTrigger(METHOD* mt);
//mapset
VMAP& GetVMap() const;
VMAP::iterator& MyMapItr() const;
BOOL HasVMap() const;
int GetArraySize() const;
private:
VMAP* m_map;
VMAP::iterator* m_my_itr;
public:
VARIABLE* m_zero;
virtual BOOL isZeroExternal();
BOOL m_ExternalZero;
int GetMethodIndex();
METHOD* GetSearchArray(int range);
METHOD* m_myParentFunc;
virtual METHOD* getParentFunc();
METHOD* m_OverParams;
virtual BOOL isOverflowParam();
BOOL m_bIsOverflowParam;
virtual METHOD* getOverParam();
METHOD* v; //node pointer : using it to pointing other METHOD class
virtual KEYWORD getMyOwnKey();
virtual RESERVED getMyOwnRes();
virtual METHOD* getMyOwnRight();
virtual METHOD* getMyOwnLeft();
virtual METHOD* getMyOwnParent();
virtual METHOD* getParentArray();
METHOD* m_mtBodyTrue;
//For Operations
virtual int getOperationRank();
//Label & goto
virtual void setValid();
//virtual BOOL getVaild();
virtual BOOL getValid();
virtual size_t getTargetToJump();
virtual void setTargetToJump(size_t setvalue);
virtual KEYWORD getKey();
virtual RESERVED getRes();
//virtual void Operation();
//for brace
virtual void SetOpenner();
virtual void SetCloser();
virtual BOOL IsOpenner();
virtual void SetCounter(size_t);
virtual size_t GetCounter();
//for Callfunc
virtual void setFunc(METHOD* func);
virtual METHOD* getFunc();
virtual void push_back_arg(METHOD* mt);
//For Reserved, Functions & Variables
//variables
virtual void Run_PostOrder();
virtual void Run_InOrder();
virtual void Operation(std::vector<METHOD*>* arg_arglist);
virtual void Operation();
//virtual void FuncOperation(METHOD* pf, void* arg_arglist=NULL);
virtual int getsize();
virtual int getsize(int arraynum);
//for Array Support Version virtuals
virtual METHOD* getArray(int arraynum);
virtual METHOD* searchArray(int arraynum);
virtual void clearArray();
virtual void CopyTotalArrayTo(METHOD* varDest) const;
virtual void CopyTotalArrayFrom(const METHOD* varSrc);
private:
static void CopyArray(VMAP* destMap, const VMAP* srcMap);
public:
virtual size_t getNumArray();
//get//////////////////////////////////////////////////////////////////////////
virtual int getInt() const;
virtual std::wstring getStr() const;
virtual float getFloat() const;
virtual int getINT();
virtual std::wstring getSTR();
virtual float getFLOAT();
virtual METHOD* getMethod() const;
//7 get
virtual int getInt(int arraynum);
virtual std::wstring getStr(int arraynum);
virtual float getFloat(int arraynum);
virtual int getINT(int arraynum);
virtual std::wstring getSTR(int arraynum);
virtual float getFLOAT(int arraynum);
virtual METHOD* getMethod(int arraynum);
//7 array-get
//14 gets
//////////////////////////////////////////////////////////////////////////
//type//////////////////////////////////////////////////////////////////////////
virtual TYPE type() const;
virtual TYPE typeCast(TYPE totype);
//2 type
virtual TYPE type(int arraynum);
virtual TYPE typeCast(int arraynum, TYPE totype);
//2 array-type
//4 types
//////////////////////////////////////////////////////////////////////////
//set//////////////////////////////////////////////////////////////////////////
//non-array set
virtual void set(const METHOD* var);
virtual void set(const int k);
virtual void set(TCHAR* start, TCHAR* end);
virtual void set(std::wstring& start, int size);
virtual void set(const std::wstring& target);
virtual void set(const float f);
//6 set
virtual void set(int arraynum, const METHOD* var);
virtual void set(int arraynum, const int k);
virtual void set(int arraynum, TCHAR* start, TCHAR* end);
virtual void set(int arraynum, std::wstring& start, int size);
virtual void set(int arraynum, const std::wstring& target);
virtual void set(int arraynum, const float f);
//6 array-set
//12 sets
//////////////////////////////////////////////////////////////////////////
//for Variable & Functions
//virtual void setName(TCHAR* name, size_t size); //삭제됨
virtual void setName(TCHAR* name);
virtual void setName(WORDCLIPPER* wc);
virtual void setName(const std::wstring& name);
virtual const std::wstring& getName() const;
virtual int getArgnum();
virtual int getNumParam();
virtual TYPE getArgTYPE(int i);
//for FOR & BREAK class
virtual BOOL isFOR();
virtual void Break();
virtual void Enter();
virtual void Leave();
virtual BOOL State();
//FOR TREES
//root setting
virtual void RootSet(METHOD* mt);
virtual METHOD* RootGet();
virtual void SetParent(METHOD* mt);
virtual void SetLeft(METHOD* mt);
virtual void SetRight(METHOD* mt);
virtual METHOD* GetParent();
virtual METHOD* getLeft();
virtual METHOD* getRight();
//for everythings
virtual int getLevel();
virtual int setLevel(int lv);
METHOD();
~METHOD();
METHOD(const METHOD&);
//addinational basic ctor
METHOD(const std::wstring& name, const std::wstring& strVal);
METHOD(const std::wstring& name, const int intVal);
METHOD(const std::wstring& name, const float floatVal);
//111213
METHOD(const std::wstring& strVal);
METHOD(const int intVal);
METHOD(const float floatVal);
//111213
METHOD operator + (const METHOD& addend) const;
METHOD operator - (const METHOD& addend) const;
METHOD operator * (const METHOD& divisor) const;
METHOD operator / (const METHOD& divisor) const;
METHOD operator % (const METHOD& divisor) const;
METHOD& operator += (const METHOD& addend);
METHOD& operator -= (const METHOD& addend);
METHOD& operator *= (const METHOD& divisor);
METHOD& operator /= (const METHOD& divisor);
METHOD& operator %= (const METHOD& divisor);
BOOL operator == (const METHOD& comptarget) const;
BOOL operator != (const METHOD& comptarget) const;
operator unsigned int() const;
operator int() const;
operator float() const;
operator std::wstring() const;
operator bool() const;
operator unsigned long() const;
operator long() const;
private:
//111213 compare
static BOOL compare_totalArray(const METHOD* first, const METHOD* second, BOOL ignoreCase_string_compare,BOOL ignore_type_difference);
static BOOL compare_single(const METHOD* first, const METHOD* second, BOOL ignoreCase_string_compare,BOOL ignore_type_difference);
void CopySingleMethodFrom_NotCast(const METHOD* from);
//only called once
void First_Initializer();
};
//this is POWER operator class.
class POWER : public METHOD {
public:
virtual void Operation(); //doing POW operation using left-child node(METHOD*) and right-child node(METHOD*). the result is saved to this class's result.
const static KEYWORD key = Key_Caret;
POWER();
~POWER();
};
//and using it in static function
//making terrain function. it decide terrain's size using parameter 2^szTile+1, 2^TileNum, 2^TilePackNum
HRESULT SETTERRAINTOTAL::SetTerrainTotal( int szTile, int TileNum, int TilePackNum, size_t Scene /*= -1*/, int resource_id /*= -1*/ )
{
#define RATION_MODE
#ifdef RATION_MODE
if(Scene == -1) Scene = vgp->GetCurrentSceneNumber();
VLogicPackage* vl = vgp->GetScene(Scene);
if(!vl) return E_FAIL;
POWER RatioTileSize; //A
RatioTileSize.SetLeft(&VARIABLE(2));
RatioTileSize.SetRight(&VARIABLE(szTile));
RatioTileSize.Operation();
POWER RatioNumTile; //B
RatioNumTile.SetLeft(&VARIABLE(2));
RatioNumTile.SetRight(&VARIABLE(TileNum));
RatioNumTile.Operation();
POWER RatioTilePack; //C
RatioTilePack.SetLeft(&VARIABLE(2));
RatioTilePack.SetRight(&VARIABLE(TilePackNum));
RatioTilePack.Operation();
if(FAILED(vl->SetTerrainTotal(
RatioTileSize+VARIABLE(1),
RatioNumTile,
RatioTilePack,
resource_id)))
return E_FAIL;
#else
if(FAILED(vl->SetTerrainTotal(
TileSize,
NumTile ,
NumTilePack ,
resource_id)))
return E_FAIL;
#endif
return S_OK;
}
問題はポイントA、B、Cのみリリースモードで発生します。
リリースモードでデバッガーを使用してトレースすると、A、B、CポイントのMETHOD()関数で、void First_Initializer()を呼び出した後、各POWERクラスの'this'ポインターは0x00000000(NULL)になります。リリースモードなので自信がありませんが、実際に問題が発生します。(そして、「デバッグモード」は問題ありません)
作成者が終了し、ステップバイステップのVisual Studioデバッガーを続行すると、POWERクラスのスタックインスタンスの仮想関数テーブルはNULLになります。
私はそれを掘り下げて、何かを知っています:この問題は、「静的関数内」と「スタックシンボル(たとえば、新しい...を使用するヒープシンボルなし)」でのみ発生します。
しかし、なぜこの問題が正確に発生するのかわかりません。
そして、私はあなたに私のひどい英語と長い長いソースコードをお詫びします。(しかし、私は最善を尽くします...私はソースコードを短くしてみました...)