12

私はこれを何時間も試していて、思いついたことをすべてグーグルで検索しましたが、気が狂いそうです。

私は構造体を持っています:

typedef struct {
  int rows;
  int collumns;
  int* mat;
  char* IDs_row;
} mem;

int* (マトリックス) と char* のサイズは後でわかります。

その際、次のように共有メモリを作成します。

mem *ctrl;
int size = (2 + ((i-1)*num_cons))*sizeof(int) + i*26*sizeof(char); //I have the real size now
shmemid = shmget(KEY, size, IPC_CREAT | 0666);
if (shmemid < 0) {
    perror("Ha fallado la creacion de la memoria compartida.");
    exit(1);
}
ctrl = (mem *)shmat(shmemid, 0, 0);
if (ctrl <= (mem *)(0)) {
    perror("Ha fallado el acceso a memoria compartida");
    exit(2);
}

ここでは問題ありません。次に、ctrl->rows と collumns に値を与え、すべての行列に 0 を割り当てます。

しかし、その後、char* と bam、セグメンテーション違反に何かを書き込みます。

プログラムをデバッグすると、mat と IDs_row の両方のポインターが null であることがわかりました。共有メモリセグメント内で正しい値を与えるにはどうすればよいですか??

試してみるために char* ポインターを削除しようとしましたが、共有メモリに接続されている他のプログラムでセグメンテーション違反エラーが発生し、マトリックス内の値をチェックしました (チェック -> 行と -> 列は成功)

4

2 に答える 2

13

まず第一に、共有メモリ セグメントに絶対ポインタを配置することは、非常に恐ろしい考えです。これらのポインタは、値を入力したプロセスでのみ有効です。共有メモリ セグメントは、すべてのプロセスで同じ仮想アドレスにアタッチされるとは限りません。shmaddr == NULL反対に、 への呼び出し時に が指定されたときに、システムが可能と判断した場所にアタッチしshmat()ます。呼び出し時に同じ仮想アドレスを指定できますが、参加しているすべてのプロセスshmat()でそのメモリ領域に他に何もマップされていないことを確認するのはあなた次第です。これをポータブルな方法で行うのは困難です。あなたが最もやりたいことは、次のいずれかです。

mem1)構造体と 2 つのデータ配列の両方に対応する 1 つの大きな共有メモリ セグメントを割り当てます。次に、絶対ポインタではなく、メモリ ブロックの先頭からの相対ポインタを配置してから、使用量を調整する必要があります。

2) 3 つの異なる共有メモリ セグメントを割り当てますが、ポインタを配置する代わりに、によって返される共有メモリ IDshmget()を配置します。

typedef struct {
  int rows;
  int collumns;
  int mat_id;
  int IDs_row_id;
} mem;

マトリックスまたは ID 配列にアクセスする必要がある場合は、対応するフィールドに格納されている共有メモリ ID にアタッチするだけです。

KEYただし、以降の の呼び出しで同じものを使用してもshmget()、期待される結果が得られないことに注意してKEY == IPC_PRIVATEください。共有メモリ ブロックには記述子 (タイプmem) をIPC_PRIVATE使用し、他の 2 つのメモリ ブロックには固定キー値を使用することをお勧めします。そうしないと、3 つの呼び出しが実際には同じ共有メモリ ブロックを返します。次の 2 つは、そのキーを持つブロックが既に存在するため、その ID を返すだけです。

于 2012-05-28T08:58:50.360 に答える
7
ctrl = (mem *)shmat(shmemid, 0, 0); 

これは、またはctrlではなく、ポインタにのみ有効なメモリを割り当てます。ctrl->matctrl->IDs_row

あなたはおそらく欲しい:

mem *ctrl;
shmemid = shmget(KEY, sizeof(ctrl), IPC_CREAT | 0666);
//allocate memory for the structure
ctrl = (mem *)shmat(shmemid, 0, 0);

//allocate memory for the int*
shmemid = shmget(KEY,((i-1)*num_cons))*sizeof(int), IPC_CREAT | 0666);
ctrl->mat = (int*)shmat(shmemid, 0, 0);

//allocate memory for the char*
shmemid = shmget(KEY,i*26*sizeof(char), IPC_CREAT | 0666);
ctrl->IDs_row = (char*)shmat(shmemid,0,0);
于 2012-05-27T19:55:13.763 に答える