0

私は宿題をしているのですが、誰かが私を助けてくれることを望んでいる奇妙な問題を抱えています。コードの途中に関数があります。

Token scheme::addScheme(vector <Token> toAdd)
{

//Check if scheme is valid
Token answer = isSchemeValid(toAdd);
if (answer.retType() != "ok")
{
    return answer;
}

identifierList * arrow = new identifierList(&(toAdd.at(0)), NULL);
idList = arrow;

for (int i = 2; i < toAdd.size()-1; i++)
{
    (*arrow).id = &(toAdd.at(i));
    (*arrow).next= new identifierList(&(toAdd.at(0)), NULL);
    arrow = (*arrow).next;
}


*id = toAdd.at(0);
openParen = '(';
closeParen = ')';

return Token("ok", "ok", 0);
}

このコードは、最後を除いて、必要なすべてのことを実行します。すべての変数を必要なものに正しく設定します。これが機能しない場所です。段階的に実行すると、最後の行を実行した直後に、Token( "ok"、 "ok"、0);が返されることがわかります。idListの値が正当な値からクレイジーな値に変更されます(たとえば、idListの行番号の最初のIDが2から-17891602に変更されます。

これは、identifierListとTokenの構成要素のヘッダーを投稿する場合に意味があります。Token:#pragma once using namespace std; #include #include #include #include #include "datalogProgram.h"

enum state {COMMA, PERIOD, Q_MARK, LEFT_PAREN, RIGHT_PAREN, COLON, COLON_DASH, MULTIPLY, ADD, SCHEMES, FACTS, RULES, QUERIES, ID, STRING, COMMENT, WHITESPACE, UNDEFINED, ENDOFFILE, START};

class Token
{
friend class datalogProgram;

public:
int lineNumber;
string type;
string value;

Token(string inType, string inValue, int inLineNum);
void route(state inState, string inValue, int inLineNum);
string retType();
string retValue();

//A list of a bunch of functions that don't matter here.
};

そしてidentifierList:

class identifierList
{
friend class scheme;
public:
Token * id;
identifierList * next;

identifierList(Token * inId, identifierList * inNext);
};

わかりません-関数から戻るだけのときに変数が変わるのはなぜですか?

4

1 に答える 1

0

これは、ベクトルtoAddが参照ではなく値によって渡されるために発生します。addScheme関数に渡したベクトルがスタックにコピーされます。

ここで、ステートメント(&(toAdd.at(0))および同様のステートメントは、ベクトルの位置0にあるものすべてを参照します。つまり、スタック上の場所へのポインタを返します。

関数が戻ると、スタックはクリアされ、スタック上の場所へのポインターにガベージが含まれます。

これを修正するには、参照によってベクトルを渡すか、(&(toAdd.at(0))を避けた方がよいでしょう。これは非常に奇妙なコントラクトであり、おそらく期待どおりに機能しないためです。

于 2013-02-28T21:20:51.240 に答える