共享内存段内的指针

Knu*_*dow 9 c linux shared-memory

我一直在尝试这几个小时,谷歌所有我想到的东西,但我会发疯.

我有一个结构:

typedef struct {
  int rows;
  int collumns;
  int* mat;
  char* IDs_row;
} mem;
Run Code Online (Sandbox Code Playgroud)

我不知道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);
}
Run Code Online (Sandbox Code Playgroud)

这里没问题.然后我给ctrl-> rows和collumns一个值,并为所有矩阵赋值0.

但在那之后,我在char*和bam中写了一些东西,分段错误.

调试程序我看到指针,mat和IDs_row都为null.如何在共享内存段中为它们提供正确的值?

我尝试删除char*指针,只是尝试一下,然后分段错误错误是在连接到所述共享内存的其他程序中,只检查了矩阵内的值(检查 - >行和 - > collumns是succesfull)

Hri*_*iev 11

首先,将绝对指针放在共享内存段中是一个非常明显的想法 - 这些指针只会在填充其值的过程中有效.不保证共享内存段在每个进程中都附加在同一个虚拟地址中.相反 - 它们附加在系统认为可以shmaddr == NULL在呼叫时指定的位置shmat().您可以在调用时指定相同的虚拟地址,shmat()但您需要确保在所有参与进程中的该内存区域上没有映射任何其他内容.这很难以便携方式进行.你最想做的是:

1)分配一个容纳mem结构和两个数据阵列的大共享内存段.那么你应该放置非绝对指针,而是相对于内存块开头的指针,然后调整使用情况.

2)分配三个不同的共享内存段,但不是把指针,把共享内存ID通过与返回的shmget():

typedef struct {
  int rows;
  int collumns;
  int mat_id;
  int IDs_row_id;
} mem;
Run Code Online (Sandbox Code Playgroud)

当您需要访问矩阵或ID数组时,只需附加到存储在相​​应字段中的共享内存ID即可.

注意尽管KEY在后续的调用中使用相同的东西shmget()不会产生预期的结果,除非KEY == IPC_PRIVATE.最好使用带有描述符(类型mem)的共享内存块的固定键值和IPC_PRIVATE其他两个内存块,否则三个调用实际上将返回相同的共享内存块 - 第一个将创建它并且接下来的两个将只返回其ID,因为具有该键的块已经存在.


Luc*_*ore 6

ctrl = (mem *)shmat(shmemid, 0, 0); 
Run Code Online (Sandbox Code Playgroud)

这仅为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);
Run Code Online (Sandbox Code Playgroud)

  • 原则是不应该将指针放在共享内存中. (2认同)