C言語関係掲示板

過去ログ

No.1199 例外処理(VC++6.0)

[戻る] [ホームページ]
No.15692

例外処理
投稿者---りえ(2004/07/20 15:47:29)


Windows2000,VC++6.0を使用しております。
try catchなんですが、下記のように記述すると例外処理は
全てcatchの方にとんでくれるのでしょうか?
try
コーディング記述
catch
エラー処理記述


No.15699

Re:例外処理
投稿者---Ban(2004/07/20 17:24:03)


VC6 だと

try
{
  コーディング記述
}
catch(...)
{
  エラー処理記述
}


と書けば基本的に全部の例外を補足出来ます。
主な注意点は以下です。
・VC6 はデフォルトで std::bad_alloc を投げない。
・VC6では関数スコープでの例外処理には対応していない。
・MFC 関係で CException のサブクラスの場合、
 明示的に例外を取得して Delete する必要がある。
  try{}
  catch(CException* x){ x->Delete(); }
catch(...){}とかが必要。
(または、TRY / CATCH マクロを使うか)



No.15705

Re:例外処理
投稿者---isshi(2004/07/20 21:41:15)


便乗質問で申し訳ありませんが、
>・VC6では関数スコープでの例外処理には対応していない。
の関数スコープでの例外処理とは具体的にどういうことなのか教えていただけないでしょうか?
今までVC6で例外処理を使ってきて、とくに問題が起きたことはないのですが。。



No.15707

Re:例外処理
投稿者---シャノン(2004/07/20 22:29:11)


こんな書き方のことかな?

#include <iostream>

class ExceptionThrower
{
public:
    ExceptionThrower()
    {
        throw this;
    }
};

class ExceptionTest
{
public:
    ExceptionTest()
        try : thrower()
    {
    }
    catch( ExceptionThrower * )
    {
        std::cout << "ExceptionThrower 例外を ExceptionTest コンストラクタで補足しました。" << std::endl;
        throw;
    }

private:
    ExceptionThrower thrower;
};

int main()
{
    try
    {
        ExceptionTest test;
    }
    catch( ExceptionThrower * )
    {
        std::cout << "ExceptionTest クラスのコンストラクタで例外が発生しました。" << std::endl;
    }

    return 0;
}


VC++ では .NET 2003 以降でないと正常に機能しないらしいです。


No.15708

Re:例外処理
投稿者---isshi(2004/07/20 23:02:05)


レスありがとうございます。
スレ主に申し訳ないので、別スレで新たに質問させていただきます。



No.15725

Re:例外処理
投稿者---りえ(2004/07/21 11:07:03)


bool型で下記のように記述した場合は
実行時にメッセージが出力されずにVC側だとおもうのですが
そのメッセージがでます。(Run-Time Check Failure #2 - Stack around the variable 'ss' was corrupted.)

int i=1000;
char ss[3];
try{
_ltoa(i,ss,10);
return true;
}
catch(char* errstr){
//エラーメッセージ出力
return false;
}



No.15728

Re:例外処理
投稿者---Ban(2004/07/21 12:44:24)


_ltoa で 1000 を文字列にすると、最低でも
ss[0] には '1'
ss[1] には '0'
ss[2] には '0'
ss[3] には '0'
ss[4] には '\0' (文字列終端)
の 5バイト分の領域が必要になると思いますが、
>char ss[3];
ss の領域が 3 バイト分しかありません。

そのため、自分の用意していない領域まで内容を
書き換えてしまい、それが不正な処理だと言われているのだと
思います。
仮にこの例外が抑制できても根本的なバグは消えませんので、
まずこの点を直してみてはいかがでしょうか。
このソースを見る限りでは多分、それで問題が原因から解消できます。

後は余談になってしまうかもしれませんが、
_ltoa は、char* 型の例外を投げてはくれませんので、
この記述では catch はまず出来ません。
# 投げられる例外の種類と _ltoa の使用は MSDN などを参照
# して確認するようにした方がいいと思います。


No.15731

Re:例外処理
投稿者---シャノン(2004/07/21 13:34:40)


>bool型で下記のように記述した場合は
>実行時にメッセージが出力されずにVC側だとおもうのですが
>そのメッセージがでます。(Run-Time Check Failure #2 - Stack around the variable 'ss' was corrupted.)

これは、書き込みをしてはいけない領域にデータを書き込んでしまった場合に出る警告ですが、例外ではありません。
不正な書き込みで発生する例外というと、いわゆる一般保護違反というのがありますが、あれは CPU が書き込みを禁止している領域に書き込もうとしたために、CPU が発生させる例外です。
対してこっちのケースは、CPU は書き込みを禁止していないけど、書き込んではいけない領域をいじってしまったために発生したものです。
禁止されていないんだから、やってもいい操作の範疇ですが、やっちゃうとプログラムが正常動作しなくなりますよ、というアプリ側のチェックに引っかかったのです。


No.15736

Re:例外処理
投稿者---Ban(2004/07/21 14:23:43)


手元の環境(Win2000 / VC6sp5)で main に元ソースを
張って実行すると、release 版でアプリケーションエラーが
出ますし、警告を無視して強行した結果これが出て、
それを調べていて例外処理〜という流れかと思ってました。