- ベストアンサー
newを使った領域の動的確保
お世話になります。 C++での記述方法なのですが 構造体Testの領域を確保しておいて値を入れます。 確保しておいた領域では領域が不足するときに 不足分を追加したいのですがどうすればよいでしょう? Cではreallocを使えばよいと思うのですが C++ではmallocではなくnewを使ったほうがよいと聞きました。 newした領域を再定義した場合(deleteせずに領域を追加) 先に領域に入れたデータは保証されるのでしょうか? 以下例文ソース*部分 以下例文のソース Test *a; a = new TEST[10]; int cnt; int i; for(i = 0;i<10;i++){ //ここでTESTの配列aに値を入れる } cnt = 12; if( cnt > 10 ){ //予想サイズを上回ったら足りない分のサイズの領域を確保し //データを入れる a = new[cnt];//*ここで領域を再確保したら元のa[0]~a[9]の //データは確実に保持されるのか? //または他に領域を確保する方法があるのか? } 上記例文ソースでは先にcntで領域を確保すれば良いようにみえますが やりたいことは 先に確保されている領域を広げて 先に入れてあったデータと、広げた領域に入れたデータを使いたい のです。 分かりにくい文章かもしれませんがよろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
直接newせずに、STLのvector等を使います。 この場合、delete[]も不要ですし、メモリ管理は内部で勝手にやってくれます。 例:push_backで追加すると、必要に応じてサイズが自動伸張される。 std::vector<Test> a(10); for(int i = 0;i<10;i++){ a.push_back(...); //ここでTESTの配列aに値を入れる // a[i] = ... みたいな記述でも可能 } int cnt = 12; if( cnt > 10 ){ a.resize(cnt); } // もしくは、最初からサイズなど気にせずa.push_backすれば // 必要に応じて自動的にサイズが増える。 # ちなみに、自分で new[] するときはdeleteもdelete[]にしてください。
その他の回答 (3)
- MrBan
- ベストアンサー率53% (331/615)
> nameにはTaro、idには1を入れたい std::vectorは「可変長配列」のように振舞うコンテナクラスですから、こんな感じで。 std::strcpy(a[0].name, "Taro"); a[0].id = 1; push_backの方は「vectorの最後尾に要素を追加(&サイズ不足なら自動拡張)」なので、a[0]に足すとか、そういう使い方をするものではないです。 test foo = { "Taro", 1 }; a.push_back(foo); // 最後に追加
お礼
本当に助かりました どうもありがとうございました(^^)
- MrBan
- ベストアンサー率53% (331/615)
#2です。補足です。 > //データは確実に保持されるのか? こちらについて解答してませんでした。 保持されません。保証もされません。 newを自分で使う場合、自分で別領域を確保してからデータをコピーし、古い領域を開放する必要があります。 また、対象がPODでない場合(クラスなど)、reallocをC++で使うと、#1の方も書かれているように、コンストラクタなどが正しく呼び出されません。 > //または他に領域を確保する方法があるのか? こちらはSTLを使うのがC++流です。 vector以外にもdequeとかlistとかmapとかあるので最適なものを選んでください。
- sha-girl
- ベストアンサー率52% (430/816)
reallocを使わない場合 データをコピーするしかありません。 if( cnt > 10 ){ Test *b = new Test[cnt]; for( int i = 0 ; i < 10 ; i++ ){ a[i] = b[i]; // 代入演算子をきちんと定義してあることが前提 } delete [] a; a = b; } 後からデータを追加したいのなら リスト構造にした方が良いですよ。 それとreallocですが同じポインタを返すとは限りません。 同じポインタでない場合は 結局別の場所に再確保してデータをコピーしています。 char* a = (char*)malloc(10); char* b = (char*)realloc(a,100000); bにはaと違うアドレスが入っている可能性があります。 >C++ではmallocではなくnewを使ったほうがよいと聞きました。 用途によると思います。 ただしmallocでクラスの領域を確保してもnewと違ってコンストラクタが呼ばれません。
お礼
どうもありがとうございました(^^)
補足
ご回答どうもありがとうございます。 vectorを使ってやってみようと思うのですが vectorを使用した場合 構造体TESTのメンバへ値を入れる記述方法がわかりません。 typedef struct test{ char name[10]; int id; } TEST; TEST構造体であるa(10)の a(0).nameとa(0).idに値をセットするにはどう記述すればいいのでしょうか? nameにはTaro、idには1を入れたい std::vector<TEST> a(10); a.push_back(const _Ty & _Val)←ソースを記述すると 記述方法のヘルプconst _Ty & _Valとでるのですが 色々調べてみましたが良く分かりませんでした。 お手隙でしたらお教え頂けると助かります。