今日こそはシューティング

だらだらと引きずってしまったが,今日こそはシューティングしなくてはならない.どこかで修正ミスを入れてしまったようだ.

printshort関数の中で例外が発生している.呼出履歴ではどこから呼び出しているのか分からない.引数の中に無効なアドレスが入っている.⇒CheckDataLinkで起きている.⇒つまらないミスがあった.

対象カードの参照をクリアしてしまっているのだから,UNDONODE:UndoCopyで親参照リンク不在が発生するのはやむを得ない.問題は,そのエラーを出したあと,ループの外でもう一度CheckDataLinkを実行すると,状態が変化して別のエラーが出てしまうという点だ.CheckDataLinkは副作用のある検査ルーチンだが,引数空で呼び出した場合には実動作は行わないようになっているはずなのだが… どこかに見落としがあるのだろうか?

動作不良が起きているのは,MARGLINK::CheckMargLinkで,対象結婚リンクは#1060で共通だ.エラーが「親参照リンク不在」から「親番号不在」に変わっている理由は,getoyanum(0)の値が,0から-1に変わってしまったためと考えられる.⇒getoyanumはMARGLINKの関数であり,refnum = margbase.kodomo[index]で得られる参照番号refnumのカードが実在し,かつ,card->cardbase.oyanums[i]で得られる結婚リンクの参照番号が当の結婚リンクの参照番号と一致すれば,i を返すという動作になっている.margbase.kodomo[index]の値が零のとき,ないし,上の操作で該当する親を見つけられなかったときは,NOPARENTSという負値を返すようになっている.

2回目のときは,cardbase.carddata.parentsがゼロになっている.どこかでこの値を書き換えているのだろう.CheckDataLink→ CheckCardLinkの呼び出しで,引数に呼び出し元の識別文字列が入っていなかった.このため,「検査中」という情報が伝わっていなかったため,実動作が発生していた.⇒UNDO操作中に不整合が発生するのは避けられないが,「カード参照番号の重複」というのはちょっとイレギュラーなのではないかと思う.

これは,カードリンクテーブル上に同一参照番号を持ったカードが2つ存在することを意味する.なんでこんなことが起きているのだろう?レコード番号!1565と!3403に@1565という同じ参照番号を持ったカードが存在している.!1565は#2602,!3403は#3196だ.どちらが悪いかと言えば,!3403の#3196ではないか?

検査ルーチンの引数で実動作するかしないかを決めているが,検査のときにNULLとしているのは致命的敗因だ.むしろ逆にするべきだった.今からでも遅くない.多少リスクはあるが,書き換えることにしよう.関係するルーチンは以下の5種だ.

  1. LINKTABLE::CheckDataLink
  2. MARGLINK::CheckMargDataLink
  3. CARDLINK::CheckCardDataLink
  4. MARGLINK::CheckMargLink
  5. CARDLINK::CheckCardLink

終わった.ミスっていなければよいが… UNDONODE::UndoCopyというエラーが出ているのはよいが,UNDONODE::UndoCopyでUNSOSYSTEM::UndoCopyを実行した後に,新しいエラーが発生する.実際にはUNDOBASE::UndoCopyを実行しているだけだが,この関数ではイメージをコピーしているだけだ.対象ノードは#3196のCARDLINKで参照番号は@3403,これに対し,shadowに入っているイメージの参照番号は1565だ.明らかにこれは何かが間違っている.現物とイメージの連結関係が崩れるということは考えづらいので,どこかで参照番号が変化していると考えるしかない.NameNarabekaeではRenumberを実行しているが,現在のコードでは止めてある.

イメージは一度複写された後は上書きされることはないと考えられるので,現物が書き換えられているのではないかと推定される.CARDDATA::refnumはpublicなのでどこからもアクセスできる.これをprivateにするのは難しいし,やってもあまり意味がないような気がする.⇒参照番号を書き込んでいる場所は12箇所ある.⇒setRefnumという関数を作っておこう.⇒この際なので,setRefnumをCARDDATAではなく,CARDBASEのメンバー関数とし,PERSONALが保持しているrefnumも同時に更新してしまうように変更しておきたい.

ただし,外部とのインタフェースではCARDDATAとPERSONALは独立に渡されるので,「外部では参照番号を更新しない」という原則を立てておく必要がある.実際には,そのようなことは起こり得ないとは思われるが… CARDLINKには既存関数として同様の処理を行うsetrefnumという関数があるが,廃止してsetRefnumに統合することにする.⇒整理できた.⇒基準ソートの場合には,UndoでRestoreNumListが実行されるが,この際に異なる参照番号が書き込まれている.


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA