2010-11-19 5 views
1

私は2次元配列をCで奇妙なことができ知っている、とのmallocで、私はこのようなものだろう:2つのFORS、配列で、Cで二重配列をshmgetおよびshmatする方法は?

/* This is your 2D array. */ 
double** matrix; 
/* The size dimensions of your 2D array. */ 
int numRows, numCols; 
/* Used as indexes as in matrix[x][y]; */ 
int x, y; 
/* 
* Get values into numRows and numCols somehow. 
*/ 


/* Allocate pointer memory for the first dimension of a matrix[][]; */ 
matrix = (double **) malloc(numCols * sizeof(double *)); 
if(NULL == matrix){free(matrix); printf("Memory allocation failed while allocating for matrix[].\n"); exit(-1);} 

/* Allocate integer memory for the second dimension of a matrix[][]; */ 
for(x = 0; x < numCols; x++) 
{ 
    matrix[x] = (double *) malloc(numRows * sizeof(double)); 
    if(NULL == matrix[x]){ 
     free(matrix[x]); printf("Memory allocation failed while allocating for matrix[x][].\n"); 
     exit(-1); 
    } 
} 

と初期化を。 は今、私は**配列に共有メモリ内のスペースを割り当てたいが、私はこれを行うことができるかどうかわからない:

shmid2 = shmget(IPC_PRIVATE, numCols * sizeof (int*), IPC_CREAT | 0700); 
my_array = (double**) shmat(shmid2, NULL, 0); 

をし、それを初期化します。これは正しいです。もしそうでなければ、私はこれをどのように正しい方法で行うことができますか?

は、配列が大きくなると、私はので、メモリの断片化のさえmalloc関数と、それをこのようにしないだろう、事前に

+0

また、if(NULL ==行列){空(行列);}が正しくありません。 –

+0

'free(NULL)'はノーオペレーションとして標準化されていますが、実際には正しいとは限りません。 – dreamlax

答えて

0

、ありがとうございました。そしてshmgetを使うと、fd(shmgetごとに1つのfdが使用されます)でも問題が発生します。

私はあなたがあなたのアプリケーション全体でNUMROWSを覚えておく必要がありますが、この方法はそれがはるかにきれいなメモリ側からである(ないCコンパイラが近くにありませんので、コンパイルされていない)、このようにそれをやって

double* matrix = malloc(sizeof(double)*numrows*numcols); 

double value = matrix[actrow*numrows+actcol]; 

free (matrix); 

をお勧めします。また、今は1つの大きなチャンクで、shmget/shmatでも同じことができます。

+0

shmgetとshamtを例にしてみてください。私はやっているようにセグフルトを起こしている... – neverMind

+0

私は後でCコンパイラを手に入れようとし、投稿します! –

+0

ありがとうございました:)私はコードのこの時点で立ち往生しており、これが原因であることがわかります。バハ! – neverMind

0

私はそれをしました!私は他の構造体と二重配列を与える例を挙げますが、あなたはその点を得ます。

私は基本的に共有メモリのセグメントに**ピクセルpixel_data(構造体image_structのメンバー、ここではイメージとしてインスタンス化されます)を割り当てたいとします。

shmid2 = shmget(IPC_PRIVATE, image->width * sizeof (pixel*), IPC_CREAT | 0700); 
    image->pixel_data = (pixel**) shmat(shmid2, NULL, 0); 

    /* Allocate integer memory for the second dimension of **pixel_data; */ 
    for (i = 0; i < image->width; i++) { 
     shmPixelId = shmget(IPC_PRIVATE, image->height * sizeof (pixel), IPC_CREAT | 0700); 
     image->pixel_data[i] = (pixel *) shmat(shmPixelId, NULL, 0); 
     if (image->pixel_data[i]== NULL) { 
      shmdt(image->pixel_data[i]); 
      printf("Sh_Memory allocation failed while allocating for pixel_data[i][].\n"); 
      exit(-1); 
     } 
    } 

マイ構造:

typedef struct pixel_t { 
    byte red; 
    byte green; 
    byte blue; 
}pixel; 

typedef struct { 
    int width; 
    int height; 
    pixel **pixel_data; 
} image_struct; 

私は次元配列ををmallocしたのと同じコードをたどるが、代わりに私は、共有メモリを使用していました。

2

これは、1つの連続した共有メモリセグメントで行うことができます。

double *matrix_data; 
double **matrix; 
int x; 

shmid2 = shmget(IPC_PRIVATE, numRows * numCols * sizeof matrix_data[0], IPC_CREAT | 0700); 
matrix_data = shmat(shmid2, NULL, 0); 

matrix = malloc(numCols * sizeof matrix[0]); 
for(x = 0; x < numCols; x++) 
{ 
    matrix[x] = matrix_data + x * numRows; 
} 

(この割り当てていることに注意してください。トリックはdoubleは、共有メモリにライブ値自体が、彼らは、共有メモリへの単なるインデックスしているので、あなたのdouble *行ポインタが、普通のmallocメモリにできることですあなたのコードがそうするように、列の主要な順序の索引は、Cの行の主要な順序では珍しいです)が一般的です。

共有メモリセグメントを共有する別々のプログラムはそれぞれを使用してmallocを使用して独自のインデックスを割り当てます。実際の配列のみが共有されます。

ところで、共有メモリ呼び出しを平文malloc()に置き換えて、同じ方法を非共有配列に使用できます。これにより、配列全体に対して1つの割り当てとインデックス用に1つの割り当てを使用できますが、コードにはという1つの割り当てが割り当てられます。

+0

これは私が2つのforsのようにダブルポインタにアクセスできることを私に保証します:printf( "array [i] [j] =%d \ n"、array [i] [j])?私は最初に幅*高さのサイズを持つ単一の配列で試してみましたが、2dim配列を持つ方が簡単で洗練されています。 – neverMind

+0

@neverMind:もちろん、あなたの不揃いの配列と同じ方法でアクセスします。 – caf

+0

問題は、私の現在のコードでは、私はそれを行うことができます。しかし、実際には共有メモリー内の配列を変更したいときは、各作業者がmy **配列の値を変更します。 S – neverMind

関連する問題