こんにちは。
開発環境は、delphiXE3 enterprise(update2適用)、win7(sp1)、sqlite3です。
漠然とした質問で申し訳ございません。
自作アプリケーションで、いろいろな操作を素早く連続でやっているとき、
たまに「アドレス違反」のメッセージが表示されます。
内部ではsetlengthして配列を動的に確保しているので、そこかなと思って
ステップ実行でやってみても何のエラーも発生しません。
ステップ実行では何度やっても発生しません。
コードは長いので載せれないですが、プログラムスピード>DBのレスポンス
スピードなため、変な動きになっているのではと思いました。
それでprocessmessagesを随所に入れてみようと考えています。
漠然としてて申し訳ございませんが、考えられる他の対処法などありましたら
教えていただけないでしょうか。
一度「アドレス違反」のメッセージが出ると、その後は何をやっても(ボタン押したりしたとしても)同じ「アドレス違反」のメッセージが出てしまうため
アプリケーションを終了するしか方法がない状況になります。
よろしくお願いします。
すみません。
アドレス違反ではなく、アクセス違反でした。
どうやらsetlengthで発生しているみたいです。
s:array of string;
setlength(s,0);
のsetlengthで出るってどういうことなのでしょうか?
>s:array of string;
>setlength(s,0);
>のsetlengthで出るってどういうことなのでしょうか?
新規のプロジェクトで、上記のコードを実行した場合でも、同じエラーメッセージが表示されますか?
SetLengthは基本的な関数で、stringの配列数を操作した程度では、
単独ではエラーにならないと思います。(ご自身でも確認している
様子ですが。)
> 内部ではsetlengthして配列を動的に確保しているので、そこかな
> と思ってステップ実行でやってみても何のエラーも発生しません。
タイミングのずれが原因というのであれば、それはもうプログラム
の作り自体の問題になりますので、根本的な原因は、ソースを見られる
方が個別に追っていくしかないと思います。
対症療法的ですが、別スレッドなどで処理が進む機能を盛り込んでいる
のであれば、その処理がかえってくるまで配列数を操作しないように
するなどの対応をすればよいのではないでしょうか。
Application.ProcessMessagesはやめて〜(それで問題が解決する理由がわかっているなら別として)
フォームのEnabledを制御する(処理中は操作を禁止)とかはどうですか?
>内部ではsetlengthして配列を動的に確保しているので、そこかなと思って
> ステップ実行でやってみても何のエラーも発生しません。
動的配列の範囲外に書き込みをしていませんか?
私も同じ現象が発生したとき範囲外に書き込みしていたことがあります。
プロジェクトのオプションで
「Delphiコンパイラ」−「コンパイル」の「実行時エラー」−「範囲チェック」
で範囲外のチェックができたはずです。
Delphi XE3 でしたら、動的配列ではなくTListなどを使うと便利です。
usesにGenerics.Collectionsを追加して
Value: TList<Integer>;
と宣言し、
Value.Add(100);
と使用します。
いろいろなご指摘ありがとうございます。
Application.ProcessMessagesは結構書き込んじゃいました。
Application.ProcessMessagesって良くないんですか?
動的配列の範囲外、指定していました(T_T)
これが原因だったんでしょうか?
「実行時エラー」−「範囲チェック」をチェックしたら、すごい沢山エラーが
出てきました。
いまエラー解除に追われていて、動的配列の範囲外が原因なのか判断できない状況です。
> Application.ProcessMessagesって良くないんですか?
という方にはお勧めしません。ともあれ動的配列の範囲チェックでエラーになるのなら
それを全て解決してから進みましょう。動的配列の範囲外にアクセスすると
Access Violationになるのは当たり前ですので。
すみません。
間違っていました。
動的配列→固定配列でした。
配列の範囲外指定を修正したら、エラーが出なくなりました。
ありがとうございました。
ツイート | ![]() |