• ベストアンサー

newとdelete

動的にaaa[5][40]という配列を作りたいのですけど,以下のプログラムでよろしいでしょうか? aaa = new double *[5]; for(int p = 0; p < 5; p++){ aaa[p] = new double [40]; } また,これをdeleteするときはどのようにすればよろしいのでしょうか? どうぞよろしくお願いいたします.

質問者が選んだベストアンサー

  • ベストアンサー
  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.1

for(int p = 0; p < 5; p++){ delete aaa[p]; } delete aaa;

graduate_student
質問者

お礼

早速の回答,ありがとうございました. 大変参考になりました.

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • floor101
  • ベストアンサー率28% (2/7)
回答No.3

気になったので補足しておきます。 ご質問の方法は確かによく使われるので、わざわざ 見にくい二次元配列的な確保をしなくても良いかも しれません。 ただ、関数の引数に渡す時の受け方が異なります。 ポインタのポインタ: func(double** p); 配列へのポインタ: func(double[][40); もしくは func(double(*)[40]); ポインタのポインタ方式は、行によって列の長さを可 変できる利点があり、配列へのポインタは、アドレス をより速く計算できる利点があります。 std::vectorを用いても構わないのであれば、 std::vector<std::vector<double> > vva(5, std::vector<double>(40)); のようにすれば、解放が不要となります。また、確保 後、行や列の数を後から変更する自由度も増えます。 欠点としては、やや効率が悪くなる事です。

graduate_student
質問者

お礼

早速の回答,ありがとうございました. vectorは近々使っていきたいと思っております. また質問する時があると思いますが,その時はどうぞよろしくお願いいたします.

全文を見る
すると、全ての回答が全文表示されます。
  • floor101
  • ベストアンサー率28% (2/7)
回答No.2

あまり美しくないキャストを伴いますが。 double (*aaa)[40] = reinterpret_cast<double(*)[40]>(new double[5 * 40]); delete[] aaa; ご質問の方法ですと、ポインタのポインタという形に なり、厳密な二次元配列とは異なります。大抵のコン パイラでは、生成されるバイナリも異なると思います。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • newで生成したものをdelete[]で破棄するのは間違い?

    int* p = new int(0); と確保したものを、普通は delete p; と書いて破棄しますが、代わりに delete[] p; と書いて破棄しても問題はないのでしょうか? 非常に悪いコードなのですが..... <1>: int* p = new int(0); <2>: int* p = new int[x]; //xはどこかで値を設定済み このうちの、1か2かのどちらかでpに対して領域を割り付けた場合に、どちらもdelete[]で破棄しても問題ないか? という意味の質問です。 コンパイルして実行しても特にエラーを吐くことはありませんでしたが非常に心配です。

  • 動的配列を宣言するためにnew演算子とdelete演算子を用いる方法が

    動的配列を宣言するためにnew演算子とdelete演算子を用いる方法があります。 2次元配列は以下のように宣言して作れるのは分かったのですが、 (実際に使って動かしてみました。) int **pp; pp = new int*[ROW]; // 行を作る for(int i = 0; i < ROW; i++) // 列を作る pp[i] = new int[COL]; http://www.asahi-net.or.jp/~uc3k-ymd/Lesson/Section02/section02_07.html(引用) 3次元配列をどのように作ったらいいか分かりません。 教えてください。宜しくお願いします。

  • 多次元配列の 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

  • newとdeleteな気がするエラー

    以下のようなプログラムを書いているのですが、delete [] ang;の行を実行すると、 Debug Assertion Failed! Program: ...\Debug\pro.exe File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp Line: 52 Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) というエラーが発生します。 fscanfを書いてからうまくいかなくなってきたので、modtorがオーバーフローしてるのかな?とも思ったのですが、特にそれらしいものは見当たりません。 いったい何が原因なのでしょうか? よろしくお願いします。 #include<stdio.h> #include<string> using namespace std; void main(void){   int i;   int ret;   static const int anum=3;   static const int LoopMax=100;   double *modtor=new double[LoopMax*anum];   double *ang=new double[LoopMax*2*anum];   const string strlearned="A.csv";   const string strlearning="_learning.csv";   FILE *fpl;   FILE *fpvnmd;   errno_t err;   double outputv[anum]={0};   double tempd;   double *tarr=new double[LoopMax];   //delete [] tarr;      //ここで消すとエラーが消える   fopen_s(&fpl,strlearned.c_str(),"r");   printf("データ読み込み\n");   for(i=0;i<LoopMax;i++){     if(fscanf(fpl,"%[^,],%lf,%lf,%lf,%lf",&tempd,&modtor[anum*i],&modtor[anum*i+1],&modtor[anum*i+2])==EOF)break;   }   fclose(fpl);     delete [] ang;   delete [] tarr;   delete [] modtor; }

  • new演算子で困っています。

    基底クラスclass1と派生クラスclass2でnewを使って同じサイズの2次元配列pとqを作ったのですが、メモリ内の同じ場所を参照してるみたいで、class2の配列qで配列の中身を書き換えたら、class1の配列pの中身も書き換えられているんですが、対処法があれば教えてください。 class class1{ protected:      int** p; public:     class1(int n)     {   int i;        *p=new int[n];        for(i=0;i<n;i++){          p[i]=new int[2];        }      }    :    : }; class class2 : public class1{     int** q; public:     class2(int n)     {   int i;        *q=new int[n];        for(i=0;i<n;i++){         q[i]=new int[2];        } }    :    : };

  • 動的配列

    二次元配列を動的に確保したいのですが,初歩的なところでつまづいてしまいました. どなたかご教授ください. C++ Builder 6を使用しております. SumF[5][40]と確保したいのです. 以下,プログラムです. ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ double **SumF; SumF = new double *[5]; for(int p = 0; p < 5; p++){ SumF[p] = new double [40]; for(int q = 0; q < 40; q++){ SumF[p][q] = new double; } } ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 「浮動小数点の不正な使用」とエラーがでます. よろしくお願いいたします.

  • classのdelete

    C++についてです。 class aaa; class bbb; とあったとします。 class aaaは、内部にclass bbb型の配列を 持っているとすると、aaaをdeleteする場合には aaaのデストラクタがcallされると思うのですが bbbのデストラクタは自動でcallされるのでしょうか (class bbbは、明示的にdeleteしないといけないのでしょうか?) 宜しく御願い致します。

  • newされたポインタとdeleteされるポインタが…

    いま私は、std::mapを使って、newされたポインタ(メモリの先頭アドレス)をkeyとして記録し、newされた場所のファイルや行番号、サイズ、何回目のnewか、などなどをvalueとして構造体にまとめて保存してデバッグなどに役立て、deleteされると同時にこの情報を破棄し、最後にすべて破棄されているかどうかを調べる(メモリリークのチェック)という機構を作っています。 ですが、keyとなっているメモリのアドレスは、多重継承や仮想継承とキャストの組み合わせ次第では、newされた時点のものとdeleteされる時点のもので異なっている場合があるため、情報を破棄することができず、行き詰ってしまいました。(無論、delete以外にも情報を引き出す際に影響が…) deleteするポインタから、そのポインタがnewで作成されたときのメモリの先頭アドレスを求める方法はないでしょうか? 以下に問題の部分だけ抽出したようなコードを挙げます。 ---------------- #include <stdio.h> class CLS1{ public: int x,y,z; virtual ~CLS1(){} }; class CLS2{ public: int x,y; virtual ~CLS2(){} }; class CLS3:public CLS1, public CLS2{ public: int x; virtual ~CLS3(){} }; void print(void* p){printf("%p\n",p);} template<typename T> T* create(T* p){ // ここで、たとえば 00854880 と記録されたとして… print(p); return p; } template<typename T> void releace(T* p){ // ここでも 00854880 と記録されてほしいが、 // 00854890 と記録されてしまう。 // この場所で 00854880 と同じインスタンスであることを確かめる方法はないでしょうか? print(p); delete p; } int main(){ CLS2* x = create(new CLS3); // 多重継承しているため、 00854890 と記録される。 print(x); release(x); return 0; }

  • newとdeleteでのアサート

    C++とViasulC++2003にて、 現在時刻を取得する関数を作成しているのですが、 以下のようなアサートが表示され強制終了してしまいます。 > _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) おそらくnewとdeleteあたりで発生しているのは確かなのですが、 その原因が解らずにこまっています。 どうか、アドバイスをよろしくお願いします。 プログラムのソースは以下の通りです。 #include <time.h> void get_date( int *year, int *mon, int *day, int *week ){ tm *mytime = new tm(); time_t long_time; time( &long_time ); mytime = localtime( &long_time ); *year = mytime->tm_year + 1900; *mon = mytime->tm_mon + 1; *day = mytime->tm_mday; *week = mytime->tm_wday; delete mytime; mytime = NULL; } int main(){ int y, m, d, w; get_date( &y, &m, &d, &w ); }

  • 同じ配列またはクラスを、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ヒープの容量を見る限りでは特に変化は見られず、素人の私では判断できないので、もしもご存知の方がいらっしゃればアドバイスいただけると助かります。 よろしくお願いします

    • ベストアンサー
    • Java