0

私はパーサーを書いていますが、キャストするときに、通常のクラス型と配列クラス型を区別するのに苦労しています。

次のようなものがあると、非常に役立ちます。

if (expression causes segmentation fault)
  do sth
else
  do sth else

そうでない場合、2 つのクラスを互いに区別する良い方法は何でしょうか?

if (base->type->GetType() != "") {
char *key = strcpy(key, base->type->GetType().c_str());
     Node *node = (stack->front).Lookup(key);

    if (node != NULL) {
      theclass = dynamic_cast<ClassDeclaration *>(node);
    }

   if (!base->GetType()->IsEquivalentTo(GetType()))
      errReport.FieldNotFoundInBase(field, type);*/
   if (theclass->id->name){ // segfault happens here.
  • 変数 theclass は、実際のクラスとして初期化されることもあれば、配列として初期化されることもあります。if (theclass->id->name) {配列クラスには実際には名前フィールドがないため、実際のクラスではなく配列クラスがある場合、セグフォルトが行で発生します。クラス変数がどの型で初期化されているかを知る方法は実際にはありません。
4

1 に答える 1

3

nodeが のインスタンスである場合、「ClassDeclaration変換済み」を[1]にdynamic_cast<ClassDeclaration *>(node)返します。それ以外の場合は、0 を返します(または、より正確には、にキャストします。nodeClassDeclaration*nullptrClassDeclaration*

値をチェックしませんnullptr。willの逆参照は、nullptrほぼ確実に segfault になります (ただし、技術的には UB であるため、何でもできます)。

ここで、何か難解なことが起こっていて、dynamic_cast失敗して返されたためにセグメンテーション違反が発生していない可能性がnullptrあります。その後、その値を逆参照しました。それが可能だ。戻り値を確認すれば、確実にわかります。


注 1:dynamic_castたとえば、キャスト先の型が複数継承されたオブジェクトの最初の基本型ではない場合、ポインター値を変更することができます。ですから、「改心した」という言葉を怖がらせるような引用符を付けるべきではなかったでしょう。

于 2013-10-20T06:35:23.030 に答える