• ベストアンサー

Vector定義の配列の共有メモリ化

Vectorの1次元配列(以下配列Vとします)を共有メモリとして、複数のアプリケーションで利用する方法がわかりません。開発ツールはVC++6.0 SP6です。 配列Vの値を参照時、書込時にはポインタ渡し(memcpy)をしたいです。コンパイルは通るのですが、アプリケーションを実行時にmemcpyを実行時に落ちます。 以下のことを確認しています。 (1)resizeでサイズは同じにしています。 (2)変数自体はNULLではありませんでした(デバッカで確認すると、アドレスがありました。) (3)変数の定義時にVectorにせず、サイズ決めた配列にするとポインタ渡しはできています。パラメータファイルを参照し、配列のサイズを決めたいので、ソース上に記入するのはできません。 よろしくお願いします。

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

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.2

>配列Vの値を参照時、書込時にはポインタ渡し(memcpy)をしたいです。 >コンパイルは通るのですが、アプリケーションを実行時にmemcpyを実行時に落ちます。 「Vectorの1次元配列」が「std::vector」の事だと仮定すると、内容の参照は「*演算子の付いたイテレータのみ」で、要素の変更は「erase()メソッドとinsert()メソッドのみ」で、行います。 各要素はポインタではアクセス出来ません。イテレータによりアクセスします。 イテレータも、インスタンスにより生成される変数ですから、その変数のアクセスには、メンバ関数を使用します。 イテレータは、見た感じ「ポインタアクセスのよう」ですが、実際の実装では「色々な演算子がオーバーライドされ、メンバ関数が呼ばれている」のです。 当然、インスタンスにより生成された変数は、memcpyなど、ポインタ渡しは出来ません。ポインタとしてmemcpyなどに渡せば、実行時に「不正なアドレスが参照される」ので、例外終了します。 また、インスタンスにより生成した変数は「生成したプロセス内でのみ有効」であり、それを共有メモリに置いて他のプロセスから参照しても、意味のあるデータにはなりません。 Windowsなど、複数のプロセスを同時に実行できるオペレーティングシステムでは「プロセスごとにメモリ空間が独立しているので、メモリアドレスは複数のプロセス間で共有する事はできない」のです。 そして「インスタンスにより生成した変数」とは、言い換えれば「オブジェクトへのポインタ変数」です。つまり「何かのメモリアドレスを持つポインタ」です。 つまり「インスタンスにより生成した変数は、中身はメモリアドレスなので、複数のプロセス間で共有する事はできない」のです。

その他の回答 (2)

  • simi5
  • ベストアンサー率71% (5/7)
回答No.3

> 配列Vの値を参照時、書込時にはポインタ渡し(memcpy)をしたいです。コンパイルは通るのですが、アプリケーションを実行時にmemcpyを実行時に落ちます。 Vectorの変数定義部分と↑の部分のソースを提示できますか? (Vectorが何か?とか、memcpyに渡しているのが具体的になにか?等分からないので。) 情報ソースは失念しましたが、std::vectorの要素は連続したメモリ領域に配置されますが、配置のされかたは配列と同じになることが保証されるというような記述がありました。 これが真実と仮定するなら、先頭の要素のポインタでmemcpyすることにより、ご希望のことが出来ると思います。(同一プロセス内での要素の参照なら、一応特定の環境で実績があります。)

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.1

共有メモリって、サイズを可変にできないので、そもそも無理があると思うな。 あと、Vectorってのは、std::vectorのことでしょうか?

関連するQ&A

  • STLのvectorで作った配列をメンバ変数にする場合は。。。

    C++初心者です。 STLのvectorで作った配列をメンバ変数は 以下のように宣言し、 class Array { public: vector<int> array; void Set(); } Array::Setのメンバ関数でarrayに値をセットします。 そして、メインからarrayを参照しようとしましたが 値が入っていませんでした。 メンバ変数の宣言の仕方が良くないのですか?

  • 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の初心者です宜しくお願いします。  今、ポインターを使わないでグローバル変数でサブルーチンから配列が使えるのかの勉強をしているのですが、 Cでは、配列をグローバル変数にとってやることは出来ないのでしょうか。  どうも正常にプログラムが実行出来ないのですが。  宜しくお願いします。

  • 関数のパラメータに配列を渡すときは、非参照型が普通なんですか?

     LippmanのC++プライマー(第4版)を勉強中です。 p.274以降に、配列に作用する関数の定義法と使用法に関する解説があり、p.275に以下の記述があります。 ■配列アーギュメント  配列パラメータも参照型と非参照型がある。  普通、配列は非参照型にする  非参照型パラメータは対応するアーギュメントのコピーで初期化される。配列アーギュメントはその配列の先頭要素へのポインタであり、そのポインタがパラメータにコピーされる。関数はアーギュメントのポインタを変更することはないが、パラメータのポインタを使って配列要素を変更することはできる。 ■配列を参照で渡すこと  配列パラメータを配列への参照にすることもできる。パラメータが配列への参照である場合、コンパイラは配列アーギュメントをポインタに変換しない。配列への参照そのものを渡す。この場合、配列の大きさはパラメータの型の一部である。コンパイラは配列アーギュメントの大きさがパラメータの大きさに一致するかどうかチェックする。 しかしp.268の「ヒント」には以下のように記されています。 ヒント:  Cの素養があるC++プログラマはアーギュメントにアクセスするためにポインタを渡すことに慣れている。 C++では、参照パラメータを使うのが安全かつ自然である。  配列パラメータも参照で渡したほうが、ポインタをコピーしないですむし、配列の大きさを越えてアクセスすることによる実行時エラーも抑止できるので、いいように思いますが、なんで「普通、配列は非参照型にする」んでしょうか?

  • Vectorでヒープエラーが出る

    下記のプログラムで、2回目のループを抜けたところでヒープエラーが 出てしまいます。 2回目のループ時にv[0]とv[1]の中のbuffが同じポインタを指してしまうことが原因のようですが、なぜ同じポインタを指してしまうのかがわかりません。 どうしたらこの問題が解決するのでしょうか? 以上、よろしくお願いします。 #include "CBuff.h" main(){ vector<CBuff> v; char *tmpstr; for (int i = 0; i < 3; i++){ if (i == 0){ tmpstr = new char[5]; memcpy(tmpstr, "aaaa", 5); }else if(i == 1){ tmpstr = new char[6]; memcpy(tmpstr, "bbbbb", 6); }else { tmpstr = new char[7]; memcpy(tmpstr, "cccccc", 7); } CBuff cb; cb.setBuff(tmpstr, strlen(tmpstr) + 1); v.push_back(cb); delete [] tmpstr; } } 【CBuff.h】 #pragma once class CBuff{ char *buff; public: CBuff(); ~CBuff(); void setBuff(char*, size_t); }; CBuff::CBuff(){ buff = NULL; } CBuff::~CBuff(){ if (buff != NULL){ delete [] buff; buff = NULL; } } void CBuff::setBuff(char *input, size_t size){ buff = new char[size]; memcpy(buff, input, size); }

  • C++BuilderでVector

    普段、vectorコンテナの可変長サイズ指定の特徴を利用していますが、一塊のコンテナの関数間でのやり取りについて、アドバイスを御願いいたします。 1)関数の引数としては、ポインタ渡しになるのですか?どんな記述になるのでしょう? 2)アクセス制限のpublic:欄に追加することで、他のクラスから参照することは可能になりますか?どんな記述になるのでしょう? 3)他の方法はありますか? よろしく御願いいたします。

  • 参照型変数へのポインタに関してです。

    参照型変数へのポインタに関してです。 たとえば int _v[10]; int &v = &_v[0]; int *pv; pv = &v;  // 参照型変数のアドレスをポインタに代入 こうすると、pv[n]と、_v[n]は同値になります。(VC++とG++では確認) これ(この使い方)で同値なのは ・c++の言語仕様 ・コンパイラの実装依存 のどちらでしょうか? WEBを漁ると「参照型変数はエイリアス(別名)」とかかれているページがヒットするので、C++の言語仕様かなと思っています。 #もちろん配列に置き換えずに単純な参照型変数として使った場合の、値の同一性は言語仕様でしょうが。

  • 2次元配列でウォッチが出来ない

    2次元配列でウォッチが出来ない 環境 windowsXP Prp Visual Stadio2003 下記の状況で2次元配列のウォッチが出来ません。 1.Visual Stadio2003を起動 2.ファイル→新規作成→プロジェクト 3.プロジェクトの種類はVisual C++プロジェクトでテンプレートからWindowsフォームアプリケーションを選択して、 プロジェクト名に「test」と入力後OKボタン押下 4.Formの適当な位置にボタンを貼り付ける 5.貼り付けたボタンをダブルクリックしてボタンクリックイベントの中(Form1.h)に以下の処理を記述する char cWork[5][20]; memcpy(&cWork[0],"こんにちは",sizeof(cWork)); 7.memcpy(&cWork[0],"こんにちは",sizeof(cWork)); にブレイクポイントを置いて、デバッグ実行をする 8.フォームのボタンを押下してブレイクポイントで止まったら「cWork」をウォッチする 9.memcpy(&cWork[0],"こんにちは",sizeof(cWork)); をステップ実行後ウォッチで内容を確認すると以下のようになります ━cWork{Length=5}char[][][] ┣━ ┣━ ┣━ ┣━ ┗━ ウォッチは出来ませんが、cWorkの中身をテキストボックスに表示や1次元配列に格納したところ cWorkに正しく値は入っていました。 ウォッチ出来ないのはVisualStadio2003のバグなのでしょうか? お分かりになられる方いらっしゃいましたらご教授お願いいたします。

  • 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; }

  • メモリとポインタと配列と

    malloc()を使用して可変の変数を作り加工。 後々に参照するためにポインタの配列に格納したいと考えております。 malloc()を行った後は必ずfree()にてメモリを開放せねばなりませんが、開放するとポインタの配列に格納した値も消えてしまいます。 だからといって開放せずにいるとメモリリークが起きてしまいます。 この様な場合はどのようにすればよろしいのでしょうか? 大体以下のような処理を考えております。 ご教授願えれば幸いです。 ****************************************   char *p[100];   for(int i=0;i<100;i++) {     char *word1 = "あいう";// ここでは固定文字を代入しているが、実際には何桁の文字列が入るかは不明。     int size = strlen(word1) + 1;     char *memo1 = (char *)malloc(size);     if (memo1 == NULL) {       printf("メモリを割り当てられません\n");       exit(1);     }     strcpy(memo1, word1);          //・     //・ *memo1 を利用した処理。     //・     char *word2 = "abc";// ここでは固定文字を代入しているが、実際には何桁の文字列が入るかは不明。     size = strlen(word1) + 1 + strlen(word2) +1;     char *memo2 = (char *)malloc(size);     if (memo2 == NULL) {       printf("メモリを割り当てられません\n");       exit(1);     }     memset(memo2, 0x00, size); //初期化     strcpy(memo2, word2);     strcat(memo2, "\t");     strcat(memo2, memo1);     p[i] = NULL;     p[i] = memo2;     free(memo2);     free(memo1);   } **************************************** 宜しくお願いします。

専門家に質問してみよう