• 締切済み

可変長配列を、動的確保した固定長配列へコピーしたい

javaではcopyintoで固定長配列へ代入できたのですが、 C++でそれに該当するものが見つからず、 newで確保した領域へmemcpyも試してみたのですが、 うまく行きませんでした。 コピー元はvector<RGBQUAD> v_rgbBMP; コピー先はRGBQUAD *rgbMemBMP; 要素数カウンタをnCntとすると rgbMemBMP = new RGBQUAD[nCnt]; memcpy(rgbMemBMP, v_rgbBMP, sizeof(v_rgbBMP)); でエラーが error C2664: 'memcpy' : 2 番目の引数を 'class std::vector<struct tagRGBQUAD,class std::allocator<struct tagRGBQUAD> >' から 'const void *' に変換できません。 ご覧のとおりSTLをよく理解しないまま、 とりあえず通常配列と同様に扱おうとして失敗しました。 現在はforで配列要素を一つ一つ代入しているのですが、 その処理は大量の画像をまとめる処理を行う核で使用しており、 何度も通過する為、できれば直接代入したいのですが、 何かよい手は無いでしょうか?

みんなの回答

回答No.4

memcpy(rgbMemBMP, &v_rgbBMP[0], v_rgbBMP.size()*sizeof(RGBQUAD));

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.3

>memcpyが高速だと言う記述をよく目にするのですが >#1のcopy()と比べて、どうなんでしょうか? copy() で十分早い。きっとボトルネックはそこではない。 vector<T> を直接 memcpy でコピーするのは実装依存のような気もする。 # 普通は配列として実装されてると思いますけど。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

普通は #1 の copy だけど, 第2引数を v_rgbBMP から &v_rgbBMP[0] にすれば memcpy でも OK だと思う. あ, 第3引数も適切に変えてね.

free_Prog
質問者

お礼

memcpyが高速だと言う記述をよく目にするのですが #1のcopy()と比べて、どうなんでしょうか? ご存知でしたら参考までにご教授ください。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

コピー先がちゃんと確保されているとして、 copy( v_rgbBMP.begin(), v_rgbBMP.end(), rgbMemBMP ); とか?

free_Prog
質問者

お礼

こちらの方法で実現できました。 ありがとうございました~

関連するQ&A

  • C++言語の配列の呼び方,動的・可変長の違い

    C++言語での配列の名称についての質問です. int Array[10]; みたいに宣言する普通の配列は「静的配列」と呼びますよね.コンパイル時に定数で要素数を指定しておかなければならないからですよね. これに対して,new[]演算子を用いて int *Array = new int[n]; といったように確保する配列はなんと呼ばれるのでしょうか. 実行後に変数を用いてその要素数を動的に指定できるので,「動的配列」と呼ぶ人が周りには多いです(「ポインタ配列」とも).しかし,C言語でのrealloc関数みたいに,直接に配列長を変化させるといったようなことはできませんよね. (改めてnew[]してmemcpy()すれば出来るのでしょうが) そこで,配列長をプログラム中で自在に変化させる方法としてstd::vectorを利用する方法がありますよね.このvectorを「動的配列」と呼ぶ人もいました. 私は,new[]したものは動的に要素数を指定できるがその後の配列長は固定であり,vectorはいつでも配列長が可変なので int Array[10]; ・・・静的固定長配列(静的配列) int n = 10; int *Array = new[n]; ・・・動的固定長配列 std::vector<int> v; ・・・可変長配列 と呼んでいるのですが,一般的にはそれぞれどのように呼ばれるのでしょうか. また,最近はstd::arrayをいうものを知りました.これについてもどのように呼ばれるのか,教えてください. よろしくお願いいたします.

  • C++ vectorに配列をプッシュしたい

    C++のstd::vectorが格納する要素として配列を指定することはできますか vectorを使って2次元配列を表現したいときは,たとえば std::vecor<std::vector<int>> v; とすれば2次元配列が表現できますよね. 2次元配列の列方向の要素数が2で固定されていて,行方向の要素数が不確定のデータを扱いたいので,2次元配列を格納するvectorで扱えればなと思いました. (2個で1組のデータがたくさんあるということなので,vectorの2次元配列ではありません) std::vector<int[2]> v; int a[2]; a[1] = 1; a[0] = 2; v.push_back(a); という書き方ではコンパイルできなかったのですが,vectorに配列要素を格納させることはできないのでしょうか. あるいは,もし可能ならどのように書けばよいのでしょうか. 結局は1組のデータセットを構造体化してそれをvectorにプッシュするやり方に落ち着いたのですが,疑問に思ったままモヤモヤしているので質問させて頂きます. 「vector 配列」などのキーワードで検索してみましたが,vectorの動的配列としての紹介記事が多くヒットしてしまい,自分ではうまく情報を発見することはできませんでした. よろしくお願いします.

  • 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言語 可変長配列

    下は可変長配列のプログラムである.提供される可変長配列に文字列を格納するにはどのようにすればよいのでしょう.使い方の例を示していただけると助かります. #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* 可変長配列の初期サイズ */ #define INIT_SIZE 5 typedef struct vector Vector; typedef Vector *VectorPtr; /* 可変長型配列の構造体 */ struct vector { char **elems; /* 要素(文字列)の配列(固定長)*/ int size; /* 可変長配列のサイズ */ int capacity; /* 可変長配列の最大容量 */ }; /* 可変長配列を生成する */ VectorPtr create_vector(void) { VectorPtr v = NULL; v = malloc(sizeof(Vector)); if (v == NULL) { fprintf(stderr, "Couldn't allocate memory for a vector\n"); exit(EXIT_FAILURE); } v->elems = malloc(sizeof(char *) * INIT_SIZE); v->size = 0; /* 初期使用サイズは 0 */ v->capacity = INIT_SIZE; return v; } /* 可変長配列の実質的な解放作業を行う. * (次々と free() するので free() 後の NULL 代入は省略) */ void delete_vector0(VectorPtr v) { int i; /* free() と同様,NULLポインタに対しては何も行わない */ if (v == NULL) { return; } /* 各要素(文字列)の領域を解放 */ for (i = 0; i < v->size; i++) { free(v->elems[i]); } free(v->elems); /* 内部配列の領域を解放 */ free(v); /* 外側の枠も解放 */ } /* 可変長配列 v を初期化する(未使用状態にするだけで領域は解放しない).*/ void clear_vector(VectorPtr v) { int i; assert(v); /* 要素の各文字列を解放 */ for (i = 0; i < v->size; i++) { free(v->elems[i]); v->elems[i] = NULL; } /* 使用サイズを0にする */ v->size = 0; } /* 可変長配列 v を拡大する */ void expand_vector(VectorPtr v) { assert(v); /* 最大容量を2倍に増やす */ v->capacity *= 2; /* 新しい最大容量を持つ領域を確保 */ v->elems = realloc(v->elems, sizeof(char *) * v->capacity); /* サイズを変更できなかった場合のエラー処理 */ if (v->elems == NULL) { fprintf(stderr, "Couldn't re-allocate memory for a vector\n"); exit(EXIT_FAILURE); } } /* 可変長配列 v の最後に文字列 s を追加 */ void append(VectorPtr v, char *s) { assert(s); /* 容量が一杯になったら容量を拡大する */ if (v->size == v->capacity) { expand_vector(v); } v->elems[v->size] = _strdup(s); /* 最後に要素を追加 */ v->size++; /* 使用部分のサイズを1つ増やす */ } /* 可変長配列の(使用部分の)サイズを返す.*/ int get_vector_size(VectorPtr v) { assert(v); return v->size; } /* 可変長配列 v における添え字 index の要素(文字列)を取得 */ char *get_elem(VectorPtr v, int index) { assert(v); /* 配列添え字の範囲をチェック */ if (index < 0 || index >= v->size) { fprintf(stderr, "Index out of bounds"); exit(EXIT_FAILURE); } /* 指定された添え字の値を返す */ return v->elems[index]; } /* 可変長配列の内容を横に並べて表示する.*/ void print_vector(VectorPtr v) { int i; assert(v); if (v->size == 0) { printf("(empty)\n"); return; } for (i = 0; i < v->size; i++) { printf(">>%s", v->elems[i]); } printf("\n"); } int main(void) { return 0; }

  • 配列のコピーをして値を返したいが

    //配列のコピーをして値を返したい import java.util.*; public class Test7_22 { static int[] arrayClone(int[] a){ int[] b = new int[a.length]; for(int i =0;i>a.length;i++) b[i] = a[i];//ここで代入されるはず return b; } public static void main(String[]args){ Scanner std = new Scanner(System.in); System.out.print("要素数:"); int n = std.nextInt(); int[] a = new int[n]; for(int i=0;i<n;i++){ System.out.print("a["+i+"]="); a[i] = std.nextInt(); } int[] x = arrayClone(a); for(int i=0;i<a.length;i++) System.out.println("x["+i+"]="+x[i]); } } //コンパイルするとb[0] = 0になる

    • ベストアンサー
    • Java
  • C++でSTLのVectorを使った構造体について

    Vectorで作った構造体配列a内でさらにVectorで宣言された配列bを作った場合、bに数値を代入するにはどうすれば良いのでしょうか? struct A {  std::vector<int> b; }; std::vector<A> a;

  • クラス・ポインタ要素の配列管理を*楽に*

    C++言語でプログラミングをしています。 大きな(可変サイズの)木構造をメモリ上に作るためにクラスへのポインタを要素に持つ配列 std::vector<T*> vector1;  (Tは定義済みのクラス)を与えて管理しています。 木のコピーを作るときに、 for(i= 0;i < vector1.size();i++)//vector1の内容をvector2へコピー { vector2.push_back(new T(*(vector1[i]))); } //ここで T::T(const T&) コピーコンストラクタが定義済み for(i= vector1.begin();i!= vector1.end();i++)//vector1の内容を削除 { delete (*i); } vector1.clear(); のような処理を実行したり、 for(i= vector1.begin();i!= vector1.end();i++)//各要素について T のメンバ関数を実行 { (*i) -> f(x); } //ここで T::f( 何らかのパラメータ ) が与えられているとする。 のようにメンバ関数を順次実行する処理をあちこちに書いているのですが、 これをテンプレートなどの形でまとめる方法ってないものでしょうか?

  • vector操作でコピーコンストラクタの抑制

    std::vector<std::vector<MyData>> vecvec; とした場合、vecvec.insert() / erase() でも MyData のコピーコンストラクタは走らないのですが、 struct MyVector { std::vector<MyData> vec; }; std::vector<MyVector> vecMyVec; とした場合、vecMyVec.insert() / erase() で、MyData のコピーコンストラクタが走ります。 MyVector が、何らかの継承と実装をすれば、回避できると思うのですが、 その方法を知ってる方がいらしたら教えてください。

  • Vector ClassのVector配列

    Vector配列からVector配列への代入などのアクセスは問題なく行えるのですが、 Vectorを入れ子にした場合?にエラーが生じてしまいます。 Class Myclass{ public: vector <int> num; }; vector <Myclass> obj; ・・・・ vector <Myclass>::iterator it=obj.begin(); vector <int> work; ・・・・ it->num=work; とするとエラーになってしまいます。 代入以外のresize()などのアクセスもエラーになってしまいますが、 vector が入れ子になっていることが関係しているのでしょうか? ご教示願います。

  • リリースモードの時にリンカエラーが発生します

    リリースモードの時にリンカエラーが発生します Visual Studioで、自作ライブラリを使ったプログラムの開発をしていたのですが、リリースモード時にリンカエラーが発生してしまいました。 デバッグモード時は特に問題なくリンクできるのですが、リリースモードでコンパイルをすると以下のようなエラーが発生します。 LibGame.lib(Game.obj) : error LNK2001: 外部シンボル ""bool __cdecl FileExists(class std::basic_string,class std::allocator >)" (?FileExists@@YA_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)" は未解決です。 LibGame.lib(Mesh.obj) : error LNK2001: 外部シンボル ""public: struct ARCHIVE_ENTRY * __thiscall CArchive::Find(class std::basic_string,class std::allocator >)" (?Find@CArchive@@QAEPAUARCHIVE_ENTRY@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)" は未解決です。 LibGame.lib(Mesh.obj) : error LNK2001: 外部シンボル ""class std::basic_string,class std::allocator > __cdecl ExtractFilePath(class std::basic_string,class std::allocator >)" (?ExtractFilePath@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@Z)" は未解決です。 Release/ShtGame.exe : fatal error LNK1120: 外部参照 3 が未解決です。 プロジェクトのプロパティ等でリンク先のライブラリを有無やヘッダをチェックしたのですが、原因がつかめませんでした。 どのようなエラー原因が考えられるでしょうか? よろしくお願いします OS:Windows XP SP3 言語:VC++ 開発環境:Visual Studio 2005 Academic Edition

専門家に質問してみよう