2012-05-27 253 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,因为具有该键的块已经存在。