掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
スタックオーバーフローなのでスタックサイズを変更したい (ID:51718)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
> デストラクタは例外処理の時に有効なのでしょうか? 有効です。 例外に伴う巻き戻しでは,巻き戻る途中に生成されたauto変数は全て破棄されます。 当然,その変数にデストラクタがあれば,デストラクタが呼び出されます。 でもって,リソース(memory, file pointer, Windows handle, etc.)を取得した場合, それを何らかのクラスのオブジェクトに代入して, そのクラスのデストラクタでリソースの解放を行う,というのは一般的な手段です。 やっていることを把握するために非常に簡単なスマートポインタを作ると, template <typename T> class SmartPointer { // 複製は禁止 SmartPointer (const SmartPointer &); SmartPointer & operator= (const SmartPointer &); T * pointer_; public: SmartPointer (T * pointer = 0) : pointer_(pointer) {} ~SmartPoitner (void) { delete pointer_; } SmartPointer & operator= (T * pointer) { if (pointer_ != pointer) { delete pointer_; pointer_ = pointer; } return *this; } T * operator-> (void) const { return pointer_; } T & operator* (void) const { return *pointer_; } T * get (void) const { return pointer_; } bool operator! (void) const { return pointer_ == 0; } }; なんてところでしょうか。 この延長で,Windows NT Kernel Handleを扱うためのクラスを用意すると, class SmartHandle { SmartHandle (const SmartHandle &); SmartHandle & operator= (const SmartHandle &); HANDLE handle_; public: SmartHandle (HANDLE handle = 0) : handle_(handle) {} ~SmartHandle (void) { if (isValid()) CloseHandle(handle_); } SmartHandle & operator= (HANDLE handle) { if (handle_ != handle) { if (isValid()) CloseHandle(handle_); handle_ = handle; } return *this; } // 若干isValidが違うかも……。 bool isValid (void) const { return handle_ != 0 && handle_ != INVALID_HANDLE_VALUE; } bool operator! (void) const { return !isValid(); } HANDLE get (void) const {return handle_; } }; なんてことになります。 こういうクラスを利用することには, +後処理のためのコードが分散したり,後処理のためにgoto使ったり,が不要になる +例外が発生した場合に,わざわざcatch (...)を使って後処理をする必要が不要になる −クラス自体にバグがあるとデバッグが困難 −大域変数が変化する可能性がある(ex:GetLastErrorの戻り値等) といった利点/欠点があります。 > ためしにどんな絵になるか描くプログラムで、何度も走らせるものではないから効率を無視してでっかい配列を扱っていたのですが、関数内でそのようなでかい変数用のメモリを確保するとstack領域に収まらずあのような事態になるようです。 > なので関数外(外部)で次のようなクラスを定義し、 > class Cood{ public: > int dat[N][N]; > Cood(){for(int i=0;i<N;i++)for(int j=0;j<N;j++)dat[i][j]=0;}}; 汎用的には,boost::arrayになるんでしょうね。 私のようにboostの使えない環境(VC++ 5.0……(泣))では, template <typename T, unsigned N> struct array { T data[N]; operator T * (void) { return data; }; operator const T * (void) const { return data; } T & operator[] (int index) { return data[index]; } const T & operator[] (int index) const { return data[index]; } ]; あたりを用意することになります。Coodは, array<array<int, N>, N> を利用して処理することになるかと。 > 関数内で、 Cood *al=new Cood; と動的?に確保?して > 値が必要なときは (*al).dat[i][j]とし、 > もう必要なくなったときに delete al;としたらうまく行きました。 > (N=2300としても上手く行きました!) スマートポインタを使って typedef array<array<int, N>, N> ArrayType; // あまりにわかりにくい型なのでtypedefした std::auto_ptr<ArrayType> al(new ArrayType); // 標準のスマートポインタstd::auto_ptr memset(&(*al)[0][0], 0, sizeof(ArrayType)); // 0で埋める とすると,delete al;は書く必要が無くなります。 operator[]を用意してやることで,(*al)[0][0]が許されます。
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2020 Takeshi Okamoto All Rights Reserved.