Victor Marconi Victor Marconi - 3 years ago 202
Linux Question

Linux Shared Memory with C++: Segmentation Fault

I'm following the Linux Programming Interface book (page 1004-1005).

I know the book uses C. But I'd like to implement the same behavior in C++. That is: share a struct between processes through shared memory.

#include <iostream>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>

using namespace std;

struct my_pair {
int a;
int b;
};

int main()
{
key_t key = ftok("aaaaa", 1);
int shmid = shmget(key, sizeof(my_pair), IPC_CREAT);
my_pair *numbers;
numbers = shmat(shmid, NULL, 0);

cout << numbers->a;

return 0;
}


It gives me this error:


shteste.cpp: In function 'int main()':

shteste.cpp:18: error: invalid conversion from 'void*' to 'my_pair*'


I understand that C++ is more strict. If I cast the return of shmat to (my_pair *), it compiles but gives me segmentation fault during execution.

Is it possible (how) to use Linux / C shared memory facilities with C++ ?

I'm compiling with: G++ 4.4.7: g++ shteste.cpp -o shteste -std=c++0x

Thanks...

EDIT: Following all sugestions, this is the code now:

int main()
{
key_t key;

if ((key = ftok("/home/alunos/scd/g11/aaaaa", 1)) == (key_t) -1) {
perror("IPC error: ftok"); exit(1);
}

int shmid = shmget(key , sizeof(my_pair), IPC_CREAT | 0640);

if (shmid == -1) {
perror("Could not get shared memory");
return EXIT_FAILURE;
}

my_pair *numbers;
void* mem = (my_pair*) shmat(shmid, NULL, 0);
if (mem == reinterpret_cast<void*>(-1)) {
perror("Could not get shared memory location");
return EXIT_FAILURE;
} else {
numbers = reinterpret_cast<my_pair*>(mem);
cout << numbers->a;
}

return EXIT_SUCCESS;
}


aaaaa contents: notacat


[scd11@VM11 ~]$ ./shteste

Could not get shared memory: Permission denied

Answer Source

This is likely a permissions issue. You can check the return values of shmget and shmat and use perror to print a human-readable error message like this.

#include <iostream>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

struct my_pair {
  int a;
  int b;
};

int main()
{
  key_t key = ftok("aaaaa", 1);
  int shmid = shmget(key, sizeof(my_pair), IPC_CREAT);
  if (shmid == -1) {
      perror("Could not get shared memory");
      return EXIT_FAILURE;
  }

  my_pair *numbers;
  void* mem = (my_pair*) shmat(shmid, NULL, 0);
  if (mem == reinterpret_cast<void*>(-1)) {
      perror("Could not get shared memory location");
      return EXIT_FAILURE;
  } else {
      numbers = reinterpret_cast<my_pair*>(mem);
      cout << numbers->a;
  }

  return EXIT_SUCCESS;
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download