2

私は単純化された Pascal パーサー/インタープリターを書いていますが、今はセグメンテーション違反について考えています。まだ取得していません。すべて正常に動作していますが、Cygwin で開発しているため、valgrind を使用してプログラムをテストすることはできません。

基本的に私がやっていることは以下のとおりです。

typedef struct{
    char idType; //Integer (i), Real (r), Char (c), String (s) or Function (f)
    union{
            int intValue;
        double fltValue;
        char chrValue;
        char *strValue;
    }idValue;
}symrec;
.
.
.
%union{
    symrec *symbol;
}
.
.
.
%destructor {
    if($$->idType == 's'){
        free($$->idValue.strValue);
    }
    free($$);
} tIdentifier tLiteralString tLiteralChar tLiteralInteger tLiteralReal

もちろん、トークンは正しく入力されています。問題は、たとえば、いくつかの式を否定する場合です。通常、新しいものを malloc する代わりに、いくつかの symrec * を再利用します。

例:

pArithmetic: tMinus pExpression { $$ = -$2; }

もちろん、これは私のコンテキストでは有効ではありません (データ型として int または double を考慮した例では)、symrec * を適切に解析していますが、このシナリオでは、デストラクタは $2 を解放せず、$$ をそのままにします。ある種のダングリングポインター?

これを書いている時点で、これが実際に起こってセグメンテーション違反が発生した場合は、$2 = NULL; を作成するだけでよいと考えています。%destructor{} 句でそれを確認しますか?

PS: 私は英語のネイティブ スピーカーではなく、これをかなり長く作成したため、混乱したアイデアについてはご容赦ください。すぐに再説明します。

4

1 に答える 1

1

いいえ、%destructors は、パーサーがエラー回復の一部としてシンボルを破棄しているときにのみ呼び出されます。

ルールが一致すると、シンボルの所有権は、通常は に転送されるか$$、ルール内で破棄されます。したがって、単項マイナスの例にはダングリングポインターがありません。

セグメンテーション違反を見つけるには、コードを で実行することをお勧めしますgdb

于 2009-07-08T10:24:51.670 に答える