具有指针的共享内存数据结构
Shared memory data structure having pointer
您好,我正在尝试使用共享内存 IPC 在进程之间进行通信。但是,当我尝试使用 shmat 将指针分配给数据结构时,shmat 返回共享内存地址的起始位置。我的代码如下
#define SHM_SIZE 10240
struct myds {
int ind;
char *data[1];
};
int main()
{
key_t key = ftok("shmfile",65);
struct myds *nums;
int shmid = shmget(key,SHM_SIZE,0666|IPC_CREAT);
char *shm_addr = (char*) shmat(shmid,(void*)0,0);
int *count = (int *) shm_addr;
*count = 5;
nums = (struct myds *)((void *)shm_addr + sizeof(int));
for(int i = 0; i < *count; i++) {
nums[i].ind = i;
}
char *t = (char*) shmat(shmid,(void*)0,0);
printf("%d\n", *count);
sprintf(t, "check- 112[=10=]");
nums[0].data[0] = t;
printf("Data written in memory:");
getc(stdin);
printf("%d\n", *count);
shmdt(shm_addr);
shmctl(shmid,IPC_RMID,NULL);
return 0;
}
*count 的最后一次打印应该打印 5,但打印出不同的值并且非常大。这似乎是 sprintf(t, "check- 112[=15=]") 的效果。我是不是做错了什么?
count
和t
指向同一个内存地址。当 sprintf()
通过 t
将新数据写入该地址时,它会覆盖通过 *count
读取的值。这就是为什么你在 sprintf()
.
之后从 *count
得到垃圾
看起来您正在尝试将 sprintf()
数据写入 nums[0].data[0]
指向的内存,但实际上您并未将 data[0]
设置为指向任何有意义的地方。 shmat()
返回的起始地址是存储在 data[0]
中的错误地址。
由于您正在分配一个非常大的内存块,远远超过实际需要的 5 个 myds
结构的数组,您可以将 data[0]
指向最后分配的 [=24= 之后的内存] 数组中的结构。
试试像这样的东西:
#define SHM_COUNT 5
struct myds {
int ind;
char* data[1];
};
int main()
{
key_t key = ftok("shmfile",65);
struct myds *nums;
int shmid = shmget(key, sizeof(int) + (sizeof(struct myds) * SHM_COUNT) + 11, 0666|IPC_CREAT);
char *shm_addr = (char*) shmat(shmid, NULL, 0);
int *count = (int *) shm_addr;
*count = SHM_COUNT;
nums = (struct myds *)(shm_addr + sizeof(int));
for(int i = 0; i < SHM_COUNT; i++) {
nums[i].ind = i;
}
char *t = (char*) (nums + SHM_COUNT);
printf("%d\n", *count);
sprintf(t, "check- 112[=10=]");
for(int i = 0; i < SHM_COUNT; i++) {
nums[i].data[0] = t;
}
printf("Data written in memory:");
getc(stdin);
printf("%d\n", *count);
shmdt(shm_addr);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
然后另一个进程可以简单地使用存储在 nums[i].data[0]
中的 char*
指针来访问每个 nums[]
元素的字符串。
如果您想为每个 nums[]
元素添加不同的字符串,只需分配足够的共享内存来容纳所有字符串,然后在该内存中相应地指向 nums[i].data[0]
。
更新:如果存储 char*
指针对你不起作用,那么存储偏移量,例如:
#define SHM_COUNT 5
struct myds {
int ind;
size_t data_offset[1];
};
int main()
{
key_t key = ftok("shmfile",65);
struct myds *nums;
int shmid = shmget(key, sizeof(int) + (sizeof(struct myds) * SHM_COUNT) + 11, 0666|IPC_CREAT);
char *shm_addr = (char*) shmat(shmid, NULL, 0);
int *count = (int *) shm_addr;
*count = SHM_COUNT;
nums = (struct myds *)(shm_addr + sizeof(int));
for(int i = 0; i < SHM_COUNT; i++) {
nums[i].ind = i;
}
char *t = (char*) (nums + SHM_COUNT);
printf("%d\n", *count);
sprintf(t, "check- 112[=11=]");
for(int i = 0; i < SHM_COUNT; i++) {
nums[0].data_offset[0] = (t - shm_addr);
}
printf("Data written in memory:");
getc(stdin);
printf("%d\n", *count);
shmdt(shm_addr);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
然后其他进程可以简单地将 nums[i].data_offset[0]
添加到它们的本地 shm_addr
地址以访问每个 nums[]
元素的字符串。
您好,我正在尝试使用共享内存 IPC 在进程之间进行通信。但是,当我尝试使用 shmat 将指针分配给数据结构时,shmat 返回共享内存地址的起始位置。我的代码如下
#define SHM_SIZE 10240
struct myds {
int ind;
char *data[1];
};
int main()
{
key_t key = ftok("shmfile",65);
struct myds *nums;
int shmid = shmget(key,SHM_SIZE,0666|IPC_CREAT);
char *shm_addr = (char*) shmat(shmid,(void*)0,0);
int *count = (int *) shm_addr;
*count = 5;
nums = (struct myds *)((void *)shm_addr + sizeof(int));
for(int i = 0; i < *count; i++) {
nums[i].ind = i;
}
char *t = (char*) shmat(shmid,(void*)0,0);
printf("%d\n", *count);
sprintf(t, "check- 112[=10=]");
nums[0].data[0] = t;
printf("Data written in memory:");
getc(stdin);
printf("%d\n", *count);
shmdt(shm_addr);
shmctl(shmid,IPC_RMID,NULL);
return 0;
}
*count 的最后一次打印应该打印 5,但打印出不同的值并且非常大。这似乎是 sprintf(t, "check- 112[=15=]") 的效果。我是不是做错了什么?
count
和t
指向同一个内存地址。当 sprintf()
通过 t
将新数据写入该地址时,它会覆盖通过 *count
读取的值。这就是为什么你在 sprintf()
.
*count
得到垃圾
看起来您正在尝试将 sprintf()
数据写入 nums[0].data[0]
指向的内存,但实际上您并未将 data[0]
设置为指向任何有意义的地方。 shmat()
返回的起始地址是存储在 data[0]
中的错误地址。
由于您正在分配一个非常大的内存块,远远超过实际需要的 5 个 myds
结构的数组,您可以将 data[0]
指向最后分配的 [=24= 之后的内存] 数组中的结构。
试试像这样的东西:
#define SHM_COUNT 5
struct myds {
int ind;
char* data[1];
};
int main()
{
key_t key = ftok("shmfile",65);
struct myds *nums;
int shmid = shmget(key, sizeof(int) + (sizeof(struct myds) * SHM_COUNT) + 11, 0666|IPC_CREAT);
char *shm_addr = (char*) shmat(shmid, NULL, 0);
int *count = (int *) shm_addr;
*count = SHM_COUNT;
nums = (struct myds *)(shm_addr + sizeof(int));
for(int i = 0; i < SHM_COUNT; i++) {
nums[i].ind = i;
}
char *t = (char*) (nums + SHM_COUNT);
printf("%d\n", *count);
sprintf(t, "check- 112[=10=]");
for(int i = 0; i < SHM_COUNT; i++) {
nums[i].data[0] = t;
}
printf("Data written in memory:");
getc(stdin);
printf("%d\n", *count);
shmdt(shm_addr);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
然后另一个进程可以简单地使用存储在 nums[i].data[0]
中的 char*
指针来访问每个 nums[]
元素的字符串。
如果您想为每个 nums[]
元素添加不同的字符串,只需分配足够的共享内存来容纳所有字符串,然后在该内存中相应地指向 nums[i].data[0]
。
更新:如果存储 char*
指针对你不起作用,那么存储偏移量,例如:
#define SHM_COUNT 5
struct myds {
int ind;
size_t data_offset[1];
};
int main()
{
key_t key = ftok("shmfile",65);
struct myds *nums;
int shmid = shmget(key, sizeof(int) + (sizeof(struct myds) * SHM_COUNT) + 11, 0666|IPC_CREAT);
char *shm_addr = (char*) shmat(shmid, NULL, 0);
int *count = (int *) shm_addr;
*count = SHM_COUNT;
nums = (struct myds *)(shm_addr + sizeof(int));
for(int i = 0; i < SHM_COUNT; i++) {
nums[i].ind = i;
}
char *t = (char*) (nums + SHM_COUNT);
printf("%d\n", *count);
sprintf(t, "check- 112[=11=]");
for(int i = 0; i < SHM_COUNT; i++) {
nums[0].data_offset[0] = (t - shm_addr);
}
printf("Data written in memory:");
getc(stdin);
printf("%d\n", *count);
shmdt(shm_addr);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
然后其他进程可以简单地将 nums[i].data_offset[0]
添加到它们的本地 shm_addr
地址以访问每个 nums[]
元素的字符串。