Как да споделя променлива char ** с помощта на споделена памет

Използвам споделена памет за комуникация между два процеса. Използвам char** за прикачване към споделеното адресно пространство. Проблемът е, че когато попълня данните за производителя и след това прикача потребителя към адресното пространство, не се прехвърлят данни. Просто получавам нулеви стойности

Това е откъс от моя продуцент

// create shared memory
shm_handle = shmget(key, BUFF_SIZE * PAGE_SIZE, IPC_CREAT | 0644);
printf("\nhandle is %d\n", shm_handle);
// valid handle?
if (shm_handle == -1) {
  printf("shared memory creation failed\n");
  exit(0);
}
// attach to shared block, see man pages for detail
buf = (char**) shmat(shm_handle, 0, 0);
if (buf == (char **) -1) {
  printf("Shared memory attach failed");
  exit(0);
}
int a = 0;
buf = malloc(sizeof(char*) * BUFF_SIZE);
for (a = 0; a < BUFF_SIZE; a++) {
  buf[a] = malloc(sizeof(char) * PAGE_SIZE);
}

и потребителя

// create shared memory
shm_handle = shmget(key, BUFF_SIZE * PAGE_SIZE, IPC_CREAT | 0644);
printf("handle is %d", shm_handle);
// valid handle?
if (shm_handle == -1) {
  printf("shared memory creation failed\n");
  exit(0);
}
char ** buft;
int a = 0;
// attach to shared block
buf = (char**) shmat(shm_handle, 0, 0);
if (buf == (char **) -1) {
  printf("Shared memory attach failed");
  exit(0);
}
buf = malloc(sizeof(char*) * BUFF_SIZE);
buft = malloc(sizeof(char*) * PAGE_SIZE);
for (a = 0; a < BUFF_SIZE; a++) {
  buf[a] = malloc(sizeof(char) * PAGE_SIZE);
  buft[a] = malloc(sizeof(char) * PAGE_SIZE);
}
printf("%s", buf[0]);

person Yanki Twizzy    schedule 14.03.2014    source източник
comment
Не мисля, че така се прави. Дали malloc не пречи и презаписва адреса на вашата споделена памет?   -  person Jiminion    schedule 14.03.2014
comment
buf = (char**) shmat(...); buf = malloc(...); изхвърляте това, което shmat ви даде, и го заменяте със скучно старо несподелено разпределение...   -  person Mat    schedule 14.03.2014
comment
Поставих malloc преди да се прикача към споделената памет, но все още беше нула   -  person Yanki Twizzy    schedule 14.03.2014
comment
Какво каза Мат! Споделената памет обикновено е само указател, а не цяло нещо, което можете да локализирате и да освободите от него, освен ако не искате сами да напишете всички тези неща.   -  person Jiminion    schedule 14.03.2014
comment
Споделената памет се връща от shmat. malloc изобщо не трябва да се използва в този случай.   -  person Marian    schedule 14.03.2014
comment
Потребителят и производителят имат ли едни и същи ключове? И трябва ли и двамата да творят?   -  person Jiminion    schedule 14.03.2014
comment
@Marian Ако не използвам malloc, нямам достъп до моя char** като двуизмерен масив. Сложих неща вътре в него, сякаш е 2D масив   -  person Yanki Twizzy    schedule 14.03.2014
comment
@Jim Да, и двамата трябва да могат да създават, така че потребителят или производителят да могат да започнат първи. Мога ли да имам указател към (указател към указател), така че споделената памет да бъде просто указател?   -  person Yanki Twizzy    schedule 14.03.2014


Отговори (2)


Вашият код не поставя вашите низове в споделена памет. Това ги поставя в купчината, както винаги прави malloc, защото вие правите:

buf = (char**) shmat(shm_handle, 0, 0);
...
/* now throw away the value of `buf` you got from shm */
buf = malloc(sizeof(char*) * BUFF_SIZE);

Това, което ще трябва да направите е:

  1. Не използвайте купчината, за да разпределите неща, които искате в споделената памет

  2. Вместо това вземете достатъчно голямо количество споделена памет за всичко, след което го копирайте, запис по запис - т.е. разположете го в паметта ръчно.

person abligh    schedule 14.03.2014

Разпределянето на неща в споделената памет е трудно и податливо на грешки, тъй като адресите на споделената памет не са непременно еднакви във всеки процес. Освен ако не предприемете стъпки, за да гарантирате, че адресите са еднакви, не можете да съхранявате указатели в споделената памет, тъй като те няма да сочат към правилното място -- вместо това трябва да съхранявате отмествания в споделената памет.

След като получите обратно частта памет от shmat, трябва сами да управлявате разпределенията в това пространство, като следите какво се използва и какво е свободно. В общия случай трябва да внедрите отново malloc/free, като използвате споделеното пространство, тъй като системният malloc/free винаги работи с несподелена купчина памет. Това е нетривиално.

Ако просто искате някакъв работещ код, който управлява това, можете да погледнете тук, но това не е лесен проблем.

person Chris Dodd    schedule 14.03.2014