2015-04-03 70 views
1

在C程序中,我創建了一個大尺寸的共享內存段,然後將可變數量的結構體放入其中(本例中爲2個)。從共享內存中讀取可變數量的結構體

strcut message * x; 
x = (struct message *)shmat(shmid,NULL,0); 
x[0].a = 1; 
x[0].b = 2; 
x[1].a = 3; 
x[1].b = 4; 

有一個擁有讀取所有寫在共享內存段的結構,但不知道結構究竟有多少讀者程序。 我曾嘗試以下方法:

struct message * x; 
x = (struct message *)shmat(shmid,NULL,0); 
while(x!=NULL) 
{ 
printf("x.a = %d\n",x->a); 
printf("x.b = %d\n",x->b); 
printf("\n\n"); 
x=x++; 
} 

它給了我2個結構正常,但之後它給了我更多的時間0(或隨機的垃圾值)(對A和B),直到用完的共享內存段,然後給出分段錯誤。 我該如何去做?

我正在使用UBUNTU。

回答

2

您正在檢查while(x != NULL) - 如果shmat()返回非NULL值(除非您將計數指針溢出,但您將提前獲得SEGV),它永遠不會爲NULL。

如果您想要將一堆結構保存在內存中,請保存它們的編號,然後在客戶端重新使用。

I.e.製片人:

char* ptr = shmat(shmid,NULL,0); 

if(ptr != ((char*) -1)) { 
    uint32_t* p_msg_count = (uint32_t*) ptr; 
    struct message* x = (struct message*) (ptr + sizeof(uint32_t)); 

    *p_msg_count = 2; // <------ 

    // Fill in x 
} 

消費者:

char* ptr = shmat(shmid,NULL,0); 
int xid, xcount; 

if(ptr != ((char*) -1)) { 
    uint32_t* p_msg_count = (uint32_t*) ptr; 
    struct message* x = (struct message*) (ptr + sizeof(uint32_t)); 

    xcount = (int) *p_msg_count; 
    for(xid = 0; xid < xcount; ++xid) { 
     // Print x[xid] 
    } 
} 

附: x = x++; - 這也很糟糕(我認爲即使編譯器也應該在這裏抱怨)。如果你想獲得「下一個」x,單獨使用前綴增量:++x

+0

Thanx @myaut,它幫助。我在做x ++時沒有遇到問題。你能詳細說一下嗎? – jps 2015-04-03 12:19:42

+1

@jps,C禁止在聲明中多次修改變量,因爲它未定義應該應用修改的順序。在你的情況下,它被分配'x ='並遞增'x ++'。後綴增量應該返回'x'的當前值,所以有可能你的代碼被編譯成:'tmp = x; ++ X; x = tmp;'和'x'永遠不會增加。可能你的意思是'x = x + 1'這是正確的? – myaut 2015-04-03 12:27:33

+0

下面是這種混淆的一個例子:[在一個語句中的索引,賦值和增量在C++和C#中表現不同。爲什麼呢?(http://stackoverflow.com/questions/1606407/index-assignment-and-increment-in-one-statement-behaves-differently-in-c-and) – myaut 2015-04-03 12:29:28