2010-11-19 32 views
1

我知道二維數組可以在C怪異,並且使用malloc,我會做這樣的事情:如何在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); 
    } 
} 

和初始化,2個FORS,數組。 現在,我想分配共享內存空間爲**陣列,但我不知道如果我能做到這一點:

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

,然後對其進行初始化。它是否正確。如果不是,我該如何正確地做到這一點?

預先感謝您

+0

另外,'if(NULL == matrix){free(matrix);'不正確。 – 2010-11-19 05:22:20

+0

'free(NULL)'被標準化爲無操作,但是你是對的,它並不真正「正確」。 – dreamlax 2010-11-19 05:32:07

回答

0

我不會做這種方式,甚至使用malloc因爲內存碎片一旦陣列變得大了。而且用shmget你也會遇到一個問題,也就是fd(每個shmget使用一個fd)。

我會建議做這種方式(未編譯因爲沒有C編譯器是關閉)

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

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

free (matrix); 

你必須在你的應用程序還記得numRows行,但這種方式是從內存方面更乾淨。此外,現在它是一個大塊,你可以用shmget/shmat做同樣的事情。

+0

你可以用shmget和shamt來舉例說明。我正在以這種方式得到一個seg故障...... – neverMind 2010-11-19 05:24:20

+0

我會盡力在以後的C編譯器上使用,並將其發佈! – 2010-11-19 05:29:15

+0

非常感謝你:)我被困在代碼的這一點,我知道這是因爲這一點。呸! – neverMind 2010-11-19 05:31:32

0

我已經做到了!我將給出一個結構,然後例如一個double數組,但你明白了。

所以,基本上我想在一段共享內存中分配一個**像素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

你可以用一個連續的共享內存段來做到這一點。訣竅是,double值本身住在共享內存,但你double *行指針可以只是普通malloc記憶,因爲他們只是一個索引共享內存:

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

(請注意,此分配按照列主要順序的索引,就像你的代碼所做的那樣,這在C行主要順序中是不常見的)。

共享共享內存段的各個程序各自分配自己的索引matrix使用malloc - 只有實際的數組被共享。

順便說一下,您可以對非共享陣列使用相同的方法,用普通的malloc()替換共享內存調用。這允許您爲整個數組使用一個分配,另外一個用於索引,而您的代碼每列有一個分配

+0

這保證了我可以訪問雙指針,就像在兩個fors中做的那樣:printf(「array [i] [j] =%d \ n」,array [i] [j])?因爲我第一次嘗試使用單個數組,寬度*高度的大小,但我發現有一個2dim數組更容易和更清晰。 – neverMind 2010-11-20 19:53:32

+0

@neverMind:是的,當然,它的訪問方式與你的不規則數組相同。 – caf 2010-11-20 21:30:04

+0

問題是,用我現在的代碼,我可以做到這一點。但是,當每個工作人員更改我的**數組的值時,實際上我想更改共享內存中的數組。訪問不是問題,但要修改它,我將不得不做更多的工作:S – neverMind 2010-11-20 21:59:53