0

I am new to boost library. I am trying to use boost::interprocess to allocate a very simple data structure in shared memory. My struct looks like this:

struct test {
    int* pInt;
    float* pFloat;
};

Here is sender.cpp:

using namespace boost::interprocess;

int main(int argc, char* argv[])
{
    // delete SHM if exists
    shared_memory_object::remove("my_shm");
    
    // create a new SHM object and allocate space
    managed_shared_memory managed_shm(open_or_create, "my_shm", 1024);

    test* i = managed_shm.construct<test>("my_solve")();
    i->pInt = new int; 
    *(i->pInt) = 2;
    
    return 0;
}

How can I get the value 2 (i->pInt) in receiver.cpp? My receiver.cpp looks like this:

int main(int argc, char* argv[])
{
    managed_shared_memory managed_shm(open_or_create, "my_shm", 1024);
    test* ans = managed_shm.find<test>("my_solve").first;
    if (ans)
    {
        std::cout << "Read from shared memory\n";
        std::cout << "print address ans: " << ans<< std::endl;
        std::cout << "print address ans->pInt: " << ans->pInt << std::endl;
        std::cout << "print value ans->pInt: " << *(ans->pInt) << std::endl;
    }
    else
        std::cout << "my_solve not found" << '\n';

    managed_shm.destroy<test>("my_solve");
    // delete SHM if exists
    shared_memory_object::remove("my_shm");

    return 0;
}

And I get error:

read access violation with *(ans->pInt)

Thanks in advance!

----------UPDATED----------

I fixed in sender.cpp by allocating like this:

    allocator<int, managed_shared_memory::segment_manager>int_alloc(managed_shm.get_segment_manager());
    test* i = managed_shm.construct<test>("my_solve")();
    auto allocated_ints = int_alloc.allocate(1); 
    i->pInt = allocated_ints.get();

But I still have the same error. Do I need to change anything in receiver.cpp?

Hien Pham
  • 11
  • 3
  • You can't, the `test` object itself is in shared memory, but the `int` you allocate with `new` is your process memory, reading it from another process directly will upset the OS. Can't you just have the `int` and `float` values directly? – Kaldrr Aug 06 '21 at 07:52
  • @Kaldrr Oh I see. This is just my test for another project, I need to create pointer in struct. So do you know how to create it in shared memory? – Hien Pham Aug 06 '21 at 08:01

1 Answers1

0

Since you allocated pInt with new int in the receiver process, it will contain an address that is only valid there. You're trying to access that address in the sender process, where it is unmapped at best or pointing to a completely different data structure at worst.

Luckily, the boost::interprocess module provides allocators that allocate memory inside the shared memory segment for you:

allocator<int, managed_shared_memory::segment_manager>
  allocator_instance(managed_shm.get_segment_manager());
auto allocated_ints = allocator_instance.allocate(100);
i->pInt = allocated_ints.get();

Note that allocators are restricted to a single type, so you will need a second allocator for your float*. See also the "quick guide for the impatient" for a copy-pastable example of allocating a std::vector<int> inside the shared memory.

Botje
  • 26,269
  • 3
  • 31
  • 41
  • I tried your example code for allocating `pInt` and I have error: `Error C2440 '=': cannot convert from 'boost::interprocess::offset_ptr' to 'int *'`. Anything wrong? – Hien Pham Aug 06 '21 at 08:17
  • Apparently you need to call `.get()` on the returned object to get a raw pointer. see edit. – Botje Aug 06 '21 at 08:22
  • Do I need to change anything in **receiver.cpp**? I still get the same error of reading access :(( – Hien Pham Aug 06 '21 at 08:39