2012-05-27 191 views
5

我一直在嘗試這個好幾個小時,而谷歌所有的東西我都會想到,但我要瘋了。共享內存段內的指針

我有一個結構:

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 *指針,只是爲了試一試,然後分段錯誤錯誤是在連接到所述共享內存的其他程序中,只是檢查矩陣內的值(檢查 - >行和 - > collumns是succesfull)

回答

5
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); 
+0

謝謝!我從來沒有想過爲每個指針做shmget。 (我甚至不知道它是如何工作的,做同樣的調用,但「鑄造」它) 現在有一個結構中的第二個整數,「collumns」的問題。我在一個進程中放置了一個「1」,另一個進程將其讀取爲62045或類似的東西。我試着將sizeof(ctrl)更改爲sizeof(men)和2 * sizeof(int)+ sizeof(int *)+ sizeof(char *),但沒有運氣。 – Knudow

+0

對不起,我發送了消息,然後進行了編輯。你能幫我多一點嗎?我現在有一個問題,結構中的第二個整數。 – Knudow

+0

@ user1420534請發佈有關這個新問題的新問題,他們似乎沒有關係。 –

7

首先,他們將絕對指針在共享內存段是可怕terible想法 - 這些指針也只是在填充其值的過程中有效。共享內存段不保證附加在每個進程相同的虛擬地址。相反 - 當撥打shmat()時指定shmaddr == NULL時,它們附加在系統認爲可能的地方。在調用shmat()時,您可以指定相同的虛擬地址,但是您可以確保沒有其他內容映射到所有參與進程中的內存區域上。這很難以便攜的方式進行。你最想做的是:

1)分配一個大的共享內存段,可容納mem結構和兩個數據數組。然後你應該放入絕對指針,而不是指向內存塊開始的指針,然後調整使用情況。

2)分配三個不同的共享存儲器段,但是不是把指針,把共享內存ID作爲返回由shmget()

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

當需要訪問矩陣或ID的數組只需附加到存儲在相​​應字段中的共享內存ID即可。

請注意,雖然在後續調用shmget()中使用相同的KEY將不會產生預期結果,除非KEY == IPC_PRIVATE。對於其他兩個內存塊的描述符(類型爲mem)和​​3210的共享內存塊,最好使用固定鍵值,否則這三個調用實際上會返回相同的共享內存塊 - 第一個會創建它,接下來的兩個將簡單地返回它的ID,因爲具有該鍵的塊已經存在。