- ベストアンサー
同じ配列またはクラスを、2回以上newしたとき
ファイルサイズ不定(ただし最大は10KB)のファイルを複数個読み込む際、ファイル個数分の配列を用意し生成するとメモリ不足になりかねないので、 読み込んだデータを使い終わったらすぐに破棄して別のデータを生成するといったような、1つの配列を使い回す方法を考えています。 (読み込んだbyte型の配列データは即座に4byte区切りでint型配列に変換し格納しています) C++なら int *p; p = new int[1024*10]; delete p; p = new int[1024*10]; delete p; みたいな方法で明示的に解放ができますが、 Javaではガーベッジコレクションで自動回収されるので 任意のタイミングで解放できないので、 int p[] = new int[1024*10]; p = null; p = new int[1024*10]; p = null; みたいな方法で試しているのですが、 こういった方法はやっぱりマズいのでしょうか? JAVAヒープの容量を見る限りでは特に変化は見られず、素人の私では判断できないので、もしもご存知の方がいらっしゃればアドバイスいただけると助かります。 よろしくお願いします
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
その他の回答 (2)
- nknk80
- ベストアンサー率65% (17/26)
- soramame99
- ベストアンサー率46% (12/26)
関連するQ&A
- newで個別に生成した配列にNULLを代入しても大丈夫か
C++にて要素数が不定の配列のクラスをnewで生成します。 このとき、newで一度に全ての配列を生成するとメモリをかなり取るので、 指定された要素番号のみを生成したいのでダブルポインタにし、 全体を生成してから個別にクラスを生成することで、 思い通りの処理ができるようになりました。 (生成する番号は0→1→2みたいな順列ではないため) しかし、ここで1つ問題が発生しました。 まずは以下にそのソースを示します。 ----------------------------- class CHOGE { int a; public: CHOGE(){ a=999; } void print(){ cout<<a<<endl; } }; ----------------------------- void main(){ CHOGE **p = new CHOGE*[3]; if( p[0] != NULL ){ // ←条件を通過してしまう cout << "ほげ~" << endl; // ←表示される //p[0]->print(); // ←当然エラー } p[0] = new CHOGE(); p[0]->print(); // ←OK delete p[0]; p[0] = NULL; delete [] p; p = NULL; } ----------------------------- 上記は3個の要素の配列を生成してから、 個別に0番目の要素のインスタンスを生成しています。 しかし、上記main関数の3行目では、 インスタンスはまだ生成していなにもかかわらず NULLチェックを通り過ぎてしまいます。 そこで上記main関数の2行目に for(int i=0; i<3; i++) p[i] = NULL; という処理を入れると期待通りに動いてくれるのですが、 どうも引っかかるといいますか、何かの情報を消してしまったり やってはいけないことをやってそうで、不安なのです・・・。 上記のようなとき、NULLを代入しても大丈夫なのでしょうか?
- ベストアンサー
- C・C++・C#
- JAVAのNEW配列生成とガベージコレクション解放
ある本に、IF文内での、JAVAの配列生成で、IF文のブロックを内で生成した配列が、ブロックを抜けた際の挙動が異なると書いてありました。 NEWを使わないで生成した配列では、解放されるが(例 int[] k = {10 , 20 , 30}; ) NEWを使って生成した配列(例 int[] hoge = new int {3}; )は メモリー内に残ってしまうということでしたが、多分その後 ガベージコレクションで解放されると思いますので問題はないのですが 両者とも、メモリー内に作成(用意)された同じような変数の箱を利用しているのに どうして挙動が異なるのでしょうか? NEWを使わないで生成した配列kは、例えばk[0]の中にアドレス参照でなく 10という値がそのまま入るのでしょうか? 分かりやすく教えていただけると助かります。 よろしくお願いいたします。
- ベストアンサー
- Java
- 多次元配列のメモリ解放
多次元配列のメモリ解放についてです。 以下のような方法で多次元配列を確保した場合に、 --- char** ppMain; ppMain = new char*[3]; for (int i = 0; i < 3; i++){ ppMain[i] = new char[20]; } --- メモリ解放する場合、 --- for (int i = 0; i < 3; i++){ delete [] ppMain[i]; ppMain[i] = NULL; } delete [] ppMain; ppMain = NULL; --- で良いでしょうか? おそらく、new/deleteの回数が同じであれば問題ないと思うのですが。 少し混乱してしまって、 delete [] ppMain[i]; によって new char*[3]で確保したところも解放されており delete [] ppMain; が必要なく危険な領域まで解放しようとしているということはないでしょうか? ご専門、お詳しいかたコメント宜しくお願いします。
- 締切済み
- C・C++・C#
- 多次元配列の new
多次元配列を new すると、どのような型のサイズの領域の配列が確保されるんでしょうか?たとえば、 int (*a)[2] = new int[3][2]; とすると、 1. 長さ2のintの配列へのポインタ型の長さ3の配列の領域が確保される のか、 2. int[3][2] すなわち、int が 6 つ分の領域が確保される のか。 今まで、「そりゃあ 2 の方だろう」と信じ込んであまり考えずにいたんですが、「コードの型形式からすると 1 の方の解釈でもいいよなぁ」と、ふと思ったものですから、質問させていただきました。 わたしの環境で調べてみると(配列用のハウスキーピング的な余分の領域とか、パディングなどは無視して)、確かに 1 の方なんですか、これで標準準拠なんでしょうかね?^^; XP Home Edition Ver.2002 SP2 cygwin v.1.0.2-1 GNU g++ v.4.1.1 ===== #include <iostream> #include <new> #include <cstdlib> struct A { char a; void *operator new(std::size_t s) { void *p = std::malloc(s); std::cout << "A::new(): " << p << '\t' << s << '\n'; return p; } void operator delete(void *p, std::size_t s) { std::cout << "A::delete(): " << p << '\t' << s << '\n'; if (p) std::free(p); } void *operator new[](std::size_t s) { void *p = std::malloc(s); std::cout << "A::new[](): " << p << '\t' << s << '\n'; return p; } void operator delete[](void *p, std::size_t s) { std::cout << "A::delete[](): " << p << '\t' << s << '\n'; if (p) std::free(p); } }; int main() { std::cout << sizeof(char) << '\t' << sizeof(A) << '\t' << sizeof(A(*)[8]) << '\n'; A *a = new A; std::cout << a << '\n'; A *aa = new A[8]; std::cout << aa << '\n'; A (*aaa)[8] = new A[8][8]; std::cout << aaa << '\n'; A (*aaaa)[8][8] = new A[8][8][8]; std::cout << aaaa << '\n'; delete[] aaaa; delete[] aaa; delete[] aa; delete a; } ===== % ./a.exe 1 1 4 A::new(): 0x870668 1 0x870668 A::new[](): 0x870678 12 0x87067c A::new[](): 0x870688 68 0x87068c A::new[](): 0x8706d0 516 0x8706d4 A::delete[](): 0x8706d0 516 A::delete[](): 0x870688 68 A::delete[](): 0x870678 12 A::delete(): 0x870668 1
- 締切済み
- C・C++・C#
- 3次元配列の動的確保
2次元配列は、 // 動的確保 int **mat = new int*[row]; for(i = 0; i < row; i++) mat[i] = new int[col]; //解放 for(i = 0; i < row; i++) delete [] mat[i]; delete [] mat; で、生成と開放はできたのですが、3次元となると、途端にわからなくなります。 かれこれ1時間半は試行錯誤はしているのですが、たどり着きそうにありません。 どなたかご教授願います。
- ベストアンサー
- C・C++・C#
- 多次元配列の new 2
追加の質問ですみません^^; char の8個の配列へのポインタの配列を new する場合などは、以下のサンプルのように typedef しないとかけないんでしょうかね?たとえば、 char (**bb)[8] = new (char (*)[8])[8]; 書きたいように思いますが、これは文法違反ですし・・・^^; ==== サンプル:(iostream の初期化時に、定義した new が呼び出されるかもしれないことを一応考慮して、stdio の関数を使っています^^) #include <new> #include <stdlib.h> #include <stdio.h> void *operator new(std::size_t s) { void *p = malloc(s); fprintf(stderr, "::new(): %p\t%lu\n", p, (unsigned long)s); return p; } void operator delete(void *p) { fprintf(stderr, "::delete(): %p\n", p); if (p) free(p); } void *operator new[](std::size_t s) { void *p = malloc(s); fprintf(stderr, "::new[](): %p\t%lu\n", p, (unsigned long)s); return p; } void operator delete[](void *p) { fprintf(stderr, "::delete[](): %p\n", p); if (p) free(p); } int main() { typedef char (*T)[8]; char (**b)[8] = new T[8]; delete[] b; } ==== % ./a.exe ::new[](): 0x6e01b0 32 ::delete[](): 0x6e01b0
- ベストアンサー
- C・C++・C#
- newとdelete
動的にaaa[5][40]という配列を作りたいのですけど,以下のプログラムでよろしいでしょうか? aaa = new double *[5]; for(int p = 0; p < 5; p++){ aaa[p] = new double [40]; } また,これをdeleteするときはどのようにすればよろしいのでしょうか? どうぞよろしくお願いいたします.
- ベストアンサー
- C・C++・C#
- STLを使わずに可変長配列を再現する方法
STLのlistが(配列に比べると)想像以上に遅かったので C++で可変長配列を再現したいのですけども 配列の拡張が思った以上に遅く困っています。 毎回newではオーバーヘッドが発生しますので、 現在は配列を一定数確保しておき 足りなくなったら配列を拡張(再確保)しています。 現在の配列のアドレスを一旦退避させてdeleteし、 新たにnewで生成して復帰させるといった感じです。 ただしこれでは、配列の要素数が増えるほど遅くなり、 オブジェクトの参照ならまだしも実体の場合は 全てコピーしなければならないので、 場合によってはSTLのlistよりも遅くなってしまいます。 newで生成してるのでできればreallocは使わずに 再現したいのですが、どうにか方法は無いでしょうか? よろしくおねがいします。 //----------------------------------------------- struct Test { int val; Test( int _val ){ val=_val; } }; Test obj1( 1 ); Test obj2( 2 ); Test obj3( 3 ); // 元のデータに代入 Test **ptr = new Test*[2]; ptr[0] = &obj1; ptr[1] = &obj2; // 退避させる Test **tmp = new Test*[2]; for( int i=0; i<2; i++ ) tmp[i] = ptr[i]; // 拡張する delete [] ptr; ptr = new Test*[4]; // 復帰させる for( int i=0; i<2; i++ ) ptr[i] = tmp[i]; delete [] tmp; ptr[2] = &obj3; //----------------------------------------------- ※NULLチェックなどはここでは省いています。
- 締切済み
- C・C++・C#
- int配列をbyte配列に変換
MIDPアプリを作成している初心者です。 Image データを一旦端末のレコードストアに保存しておく為、 getRGB()で取得したint配列を、byte配列に変換しなくてはいけません。 ↓のように レコードストアに書き込むメソッドを書いてみました。 public void writeRecordStore( String name, Image image ) { int width = image.getWidth(); int height = image.getHeight(); int[] pxData = new int[ width*height ]; byte[] byteData; RecordStore rs = null; try { //画像をバイトデータに変換 image.getRGB( pxData, 0, width, 0, 0, width, height ); //レコードストアを開く rs = RecordStore.openRecordStore( name, true ); //バイト配列に変換 ← ここがわからない //レコードの追加 rs.addRecord( byteData, 0, byteData.length ); } catch( Exception e ) { } } int配列をbyte配列に変換する方法わかる方 ご教授の程お願いします。 また、まだコーディングに自信が無いので、文法のミスもご指摘頂けたらありがたいです。
- ベストアンサー
- Java
- クラス内にnewで形成した配列等が含まれる場合
クラスを関数内に作成した時にそれを実体コピーさせるreturnで返したいんですが、class内newで形成した動的配列があるため、返した後デストラクタが呼ばれるので動的配列の中身が消滅してしまう(させている)のですが、動的配列の消去にデストラクタを使用しないようにするしかありませんか? class a{ public: int *b; a(){b=new int[10];} ~a(){delete b;} //エラー原因 a operator+(a &s){a c;c.b[0] = b[0] + s.b[0];return c;} }; void main() {a x,y;y = x + x;}
- ベストアンサー
- C・C++・C#