• ベストアンサー

共有メモリについて

shmget関数のサイズ指定について質問があります。 共有メモリ上にキー番号「1234」で作られている状態で、 以下の関数(サイズ指定ありなし)を呼び出した際の違 いは何なのでしょうか? 単純にキー1234にアタッチしたいだけなら、サイズ0指定を 使用するのでしょうか? shmget(1234,0,IPC_ALLOC) shmget(1234,sizeof(int),IPC_ALLOC)

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

  • ベストアンサー
  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.6

IPC_ALLOC は、どうやら、単に 0 と定義されているマクロではなさそうですね。 http://www-igm.univ-mlv.fr/~dr/HEVEA/ なので、mode_t mode = SHM_R | SHM_R >> 3 | SHM_R >> 6; (適当に決めたアクセスモード)として、  shmget(1234, 0, mode); と、  shmget(1234, sizeof(int), IPC_ALLOC | mode); の意味は違うかもしれませんね^^ 上の方は単に存在すればよく、下の方は存在してかつ size をチェックし size が同じ(あるいはそれ以上)という意味になるのかもしれません。移植性を考慮するなら、IPC_ALLOC は使わないほうがいいと思いますけれど…^^ レスがあまりないので、表示通りに「困って」る風には思えないので、まあいいんでしょうけど(笑)参考までに^^

ankomoti
質問者

お礼

レスが遅くなり申し訳ありません。 やはりIPC_CREATとかを使った方がよさそうですね。 どうもありがとうございました。

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

その他の回答 (5)

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.5

お使いの環境は solaris(なつかしい^^)ですか?今は、どのUnix OSでも存在するのかな? http://search.luky.org/linux-users.0/msg00218.html でもまあ、移植性を重要視するなら、IPC_CREAT と IPC_EXCL その他モード指定マクロのみ使ったほうがいいような感じもします。

全文を見る
すると、全ての回答が全文表示されます。
  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.4

そうなんですか。じゃあ、IPC_ALLOC は、単に 0 と定義されてるマクロですかね。POSIX でも規定されてるのかしら?^^ 『IPC_ALLOCは既に存在するものを使うこと』を意味するなら、size 引数は 0 にしないといけないんじゃないですかね?^^ わたしは、IPC_CREAT | IPC_EXCL というのは使ったことはありますけど^^ これは、存在しなければ作るが、存在すればエラーにする、という意味だったと思います。

全文を見る
すると、全ての回答が全文表示されます。
  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.3

ただし、key に IPC_PRIVATE を指定していない場合の話だと思いますけど^^

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

すみません。ankomoti「さん」が抜けてました^^;

全文を見る
すると、全ての回答が全文表示されます。
  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.1

shmget(key, size, shmflg) の第2引数の size は、共有メモリ領域の最小サイズを指定します。新たな領域(たとえば、サーバ側で)を作成する場合は、実際に取りたい領域のサイズ以上のものを指定しないといけない。既存の領域(たとえば、クライアント側で)を参照する場合は、size に 0 を指定するんだと思いますよ。なので、ankomoti のおっしゃるとおり、アタッチしたいだけなら、0 と指定すべきだと思います。   ところで、IPC_ALLOC なんてのはありましたっけ?^^; IPC_CREAT ですか??

ankomoti
質問者

補足

早速のコメントありがとうございます。 IPC_ALLOCは既に存在するものを使うことを指示します。存在し なければエラーらしいです。

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

関連するQ&A

  • 複数の共有メモリの作成

    同じPC内に複数の共有メモリを作ろうとしています。自分の考えでは共有メモリを作成するときに shmget(key_t key, int size, int shmflg) のkeyを変えれば複数の共有メモリを作れると思ったのですがうまくいきません。ちなみにkeyは key = ftok(const char *pathname, int proj_id); で取得していて、pathnameとproj_idを変えればkey_tの値も変わり、複数の共有メモリが確保できると思ったのですが・・・。 また、ipcsで確認したところできた共有メモリのキーが0xffffffffになっているのも気になりました。普通は0x00000000になるべきなんでしょうか?

  • 共有メモリの削除

    Cでunix系のネットワークプログラムをくんでいます。 シェアードメモリ(共有メモリ)を使用して作業していますが、 あるブロックを指定して共有メモリを削除する方法はどうすればよいですか? *shmclientという構造体の共有メモリがあります。 n番目の共有メモリを削除したいです。 memcpy((char *)(shmclient+n), 0, sizeof(shmclient)); 上のように0(NULL)をコピーしましたが成功しませんでした。 よろしくお願いします。

  • 共有メモリへのマッピング(MapViewOfFile)について

    共有メモリについて(特にMapViewOffileについて)教えてください。 ある構造体と、あるデータAを共有メモリへマッピングしたい考えています。 構造体は、 typedef struct _Data { int length; long data; char mIntArrayData[256]; } Data; データAは、short型の配列(要素数はx*y*z,x,y,zはcsvファイル等から読み込む)で、サイズをdatasize = sizeof(short) * x * y * z;とします。 この2つを使って、 両方のデータを long AllDataSize = sizeof(Data) + datasizeとしました。 このサイズを使って、共有メモリのマップハンドルを hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,PAGE_READWRITE,AllDataSize,MAPPED_FILE_NAME); (MAPPED_FILE_NAMEは、 メモリマップドファイルの名前) で、生成しました。 生成はできたのですが、データAにアクセスするための下記のような時にマッピングに失敗してしまいました。 DWORD dwOffset = sizeof(DATA); short *pData = (short *)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, dwOffset, Bytes); (Bytesはマッピングしたいバイト数でsizeof(short)の倍数) 次のようなDATAにアクセスするマッピングには成功しています。 DWORD dwOffset = 0; DATA *pDATA = (DATA *)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, dwOffset, sizeof(DATA)); 色々なサイト等を調べて、考えてみたのですが、怪しいところはdwOffsetと、CreateFileMappingで、マッピングしたい全体のファイルサイズを、構造体とデータAのサイズの単純な足し算としているところと考えています。ただ、はっきりとした答えが全くわからないので、どうか御教授お願いします。

  • C++ 最適なメモリ確保

    画像処理をするために実験的にC++でプログラムを書いています。 malloc関数でBMP画像の画素位置を、画像画素分確保するだけのint型配列を作成するにはどうしたらよいでしょうか。 因みに、入力画像の解像度は640x480です。 一番左下の画素を(x,y)=(0,0)として考えています。 ある条件の画素に該当する画素座標を、下のStackX,StackYにx,y成分ごとに格納していくものです。 //////// int *StackX = (int *)malloc(sizeof(int)*100000); int *StackY = (int *)malloc(sizeof(int)*100000); //////// 上のように書くと、途中でクラッシュしてしまいます。 ですが、大目にメモリをとって //////// int *StackX = (int *)malloc(sizeof(int)*10000000); int *StackY = (int *)malloc(sizeof(int)*10000000); //////// で実行すると、最後まで動いてくれます。

  • 動的メモリの初期化方法について。

    char *p = new char[SIZE]; 上記の方法で動的メモリを確保した場合 確保したメモリの初期化は、 memset(p, 0x00, SIZE); のほかに方法はありますでしょうか? 個人的にSIZEを指定してしまうのがキレイではないような気がしています。 memset(p, 0x00, sizeof(p)); では、sizeof(p)はchar* のサイズなので正しく初期化できず、 for (int i = 0; i < SIZE; i++){ memset(p[i], 0x00, sizeof(p[i])); } では、コンパイルエラーが出てしまいます。 (new char[SIZE]で確保した場合には、p[i]のように配列としてアクセスできないのでしょうか? 単にchar p[SIZE]の場合には、当然配列としてアクセスできるのに。。。) 一般的な初期化方法のほかにも何かコメントでも良いので経験あるかたいらっしゃいましたら教えてください。 宜しくお願いいたします。

  • 引数が配列のときの関数内でのsizeofについて

    こんにちは. Cを勉強している最中に疑問にあったことを質問させていただきます.以下のプログラムで配列myarrayの中の最大のメンバーを見つけるプログラムです.コメントアウトしてある //int ary_size = sizeof(myarray)/4; をグローバル変数で定義するとうまく最大の数を見つけてくれるのですが, 関数の中で int ary_size = sizeof(ary)/4; と定義するとうまくいきません.そこで,以下の printf("The size of the ary is %d\n",ary_size); という表示を追加したところ,ary_size = 1となっていることが分かりました. なぜそうなるのでしょう?関数の引数はint ary[]の配列なので,sizeof(ary)でaryがメモリ中で占めるバイト数が得られるんじゃないんですかね?ちなみに私の環境ではsizeof(int)は4バイトなので int ary_size = sizeof(ary)/4; と割る4で配列のメンバーの数を求めています. 初心者の質問ですみませんがよろしくお願いします. #include <stdio.h> #include <Windows.h> int myarray[] = {1,2,3,4,5,6,7,2}; int FindMax(int ary[]); //int ary_size = sizeof(myarray)/4; int main() { int max; max = FindMax(myarray); printf("The maximum value is %d\n",max); Sleep(2000); return(0); } int FindMax(int ary[]) { int ary_size = sizeof(ary)/4; int i; int max; max = ary[0]; for(i=1;i<ary_size;i++) { if(ary[i]>max) { max = ary[i]; } } printf("The size of the ary is %d\n",ary_size); return(max); }

  • 64ビットのlinuxで32ビットメモリモデルの指定のしかたを御教えください

    大量のメモリを必要とする処理のため、64ビットlinuxの環境でgccを使っております。この環境ですと、当然ポインタが64ビットなのですが、同じ環境で動かすその他のツールはそんなにメモリを使いません。こちらの方はメモリの節約のため、できれば32ビットのメモリモデルを使いたいのです。また、古いプログラムがsizeof(ポインタ) == sizeof(int)が前提で作られているものがあり、いずれ書き直す予定ではありますが、とりあえず動かしてみたいのです。gcc に与えるスイッチの指定などを御教えください。

  • malloc関数によるメモリの確保

    C初心者です。 malloc関数によるメモリの確保に関して教えてください。 2次元配列のサイズに対してmalloc関数の引数値をたとえば、 (double*)malloc(datasize*sizeof(double)) などとしメモリ領域を確保すると、メモリアドレスはデータのサイズ によらず一定 1234044、1234048となります。 データサイズを大きくし、datasize*sizeof(double)が16Kバイトを超えるとcmd.exeがエラーとなり落ちます。 デバックモードで実行すると 「"System.AccessViolationException"のハンドルされていない例外が不明なモジュールです。で発生しました。 追加情報:保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリがこわれていることが考えられます」 というメッセージがでます。 コンパイラはExpressEdition2008です。 この現象を回避するにはどうすべきか、なぜこのようなことが起こるのかご教授ください。 よろしくお願いいたします。

  • メモリ動的確保について

    こんにちはです。 メモリの動的確保なのですが、 typedef struct DATA{ char name[256]; char pass[256]; int money; }BANK; void insert(BANK *p,int max); int main(){ int i; size_t st; BANK *person; person = (struct DATA *)malloc(sizeof(struct DATA)); //person = (struct DATA *)malloc(5); if(person == NULL){ printf("確保失敗\n"); exit(-1); } //memset(person,'\0',sizeof(struct DATA)); と、言う風に、記載ソースは途中ですがメモリをとりました。 mallocの後ろの部分ですが、sizeof(struct DATA)と5ではどうちがうのでしょう??2通りともコンパイルエラーはないです。 5は動的に最大5までとるって事はわかるのですが、struct DATAの方はいくつとるのです??いくつもで入力次第です? そして、動的したのにたいしてmemsetしたら実行エラー(コンパイルは通りました)おきました。動的にたいしてmemはダメなのでしょうか? アドバイスいただけたらありがたいです。宜しくお願いいたします。

  • 動的メモリの確保の仕方を教えて下さい。

    プログラミングの初心者なのですが、現在256x256x100のバイナリファイルを読み込もうとしているのですが、下のように書くとエラーになってしまいます。動的メモリの確保を行えば、上手くいくと思うのですが。。どなたか教えて頂けないでしょうか?どうぞよろしくお願いします。 const short int SIZE=256; const short int SLICE=100; signed short int matrix[SLICE][SIZE][SIZE]; for(int i=0; i<SLICE; i++){ for(int j=0;j <SIZE; j++){ for(int k=0;k<SIZE; k++){ fin.read((char*) &matrix[i][j][k],sizeof(signed short int)); cout<< matrix[i][j][k]<<endl; } } }

子機で相手の声が聞こえない
このQ&Aのポイント
  • 子機で相手の声が聞こえないトラブルについて相談します。お使いの製品はMFC-J737DNです。
  • Windows OSをお使いで、無線LANで接続されています。ひかり回線をお使いですか?関連するソフト・アプリはありません。
  • 相手の声が聞こえない問題の解決方法についてお知らせします。ブラザーのインクジェットプリンターの子機に関するFAQもご覧ください。
回答を見る