[Boost-users] Help with custom classes PLEASE!!

69 views
Skip to first unread message

Daniel Veneros

unread,
Feb 1, 2010, 4:23:41 PM2/1/10
to boost...@lists.boost.org
Hi, I am trying to create a shared memory segment where I can share a STRING between 2 process, I tried using the following code:

In the "main" process:

#include <boost/interprocess/managed_shared_memory.hpp>

#include <boost/interprocess/containers/vector.hpp>

#include <boost/interprocess/allocators/allocator.hpp>

#include <cstdlib>

#include <string>

#include <iostream>


using namespace boost::interprocess;


typedef allocator<std::string, managed_shared_memory::segment_manager> ShMemAllocator;

typedef vector<std::string, ShMemAllocator> MyVector;



int main(int argc, char** argv) {

    struct shm_remove {

        shm_remove() {shared_memory_object::remove("MySharedMemory"); }

        ~shm_remove() {shared_memory_object::remove("MySharedMemory"); }

    }remover;


    managed_shared_memory segment(create_only, "MySharedMemory", 65536);


    const ShMemAllocator alloc_inst(segment.get_segment_manager());


    MyVector *myVector = segment.construct<MyVector>("MyVector")(alloc_inst);


        myVector->push_back("a");


    int stop; //this line helps me wait until i run the other process

    std::cin >> stop;


    return (EXIT_SUCCESS);

}



at the "client" process:

#include <boost/interprocess/managed_shared_memory.hpp>

#include <boost/interprocess/containers/vector.hpp>

#include <boost/interprocess/allocators/allocator.hpp>

#include <cstdlib>

#include <string>

#include <iostream>

using namespace boost::interprocess;



typedef allocator<std::string, managed_shared_memory::segment_manager> ShMemAllocator;

typedef vector<std::string, ShMemAllocator> MyVector;



int main(int argc, char** argv) {

    managed_shared_memory segment(open_only, "MySharedMemory");



    MyVector *myVector = segment.find<MyVector>("MyVector").first;

     std::cout << "myVector size: " << myVector->at(0) << std::endl;   


    return (EXIT_SUCCESS);

}



When I run both I receive an error "Segmentation Fault, Core Dumped"...

Does anyone know how to solve this?


Thanks


Dann


Steven Watanabe

unread,
Feb 1, 2010, 4:42:21 PM2/1/10
to boost...@lists.boost.org
AMDG

Daniel Veneros wrote:
> Hi, I am trying to create a shared memory segment where I can share a STRING
> between 2 process, I tried using the following code:
>

> *In the "main" process:*


>
> #include <boost/interprocess/managed_shared_memory.hpp>
> #include <boost/interprocess/containers/vector.hpp>
> #include <boost/interprocess/allocators/allocator.hpp>
> #include <cstdlib>
> #include <string>
> #include <iostream>
>
>
> using namespace boost::interprocess;
>
>
> typedef allocator<std::string, managed_shared_memory::segment_manager>
> ShMemAllocator;
>
> typedef vector<std::string, ShMemAllocator> MyVector;
>

You can't use std::string. You need to use
boost::interprocess::basic_string
with an appropriate allocator (just as you need to use
boost::interprocess::vector
instead of std::vector).

In Christ,
Steven Watanabe

_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Daniel Veneros

unread,
Feb 1, 2010, 4:50:49 PM2/1/10
to boost...@lists.boost.org
Hi,
Thanks, this works now...

I got one othr question, what if I want to share a MAP type between both processes? a map that has a string as a key and a custom class as a value?
I mean:

class Employee {
private: 
string name;
int age;

public:
Employee();
~Employee();
};

map<string, Employee>

Somehing like that... how can I implement that? I tried doing this:

using namespace boost::interprocess;


map<std::string, Employee> myMap;

typedef allocator<myMap, managed_shared_memory::segment_manager> ShMemAllocator;

typedef vector<myMap, ShMemAllocator> MyVector;


But it's not working...

THANKS!!!


Dann




Steven Watanabe

unread,
Feb 1, 2010, 4:59:50 PM2/1/10
to boost...@lists.boost.org
AMDG

Daniel Veneros wrote:
> I got one othr question, what if I want to share a MAP type between both
> processes? a map that has a string as a key and a custom class as a value?
>

The map and the string both need to have allocators.

Daniel Veneros

unread,
Feb 1, 2010, 5:17:43 PM2/1/10
to boost...@lists.boost.org
And what about the class?
Do i just need to  create allocators for the map and the string(the map's key)??


     typedef allocator<basic_string, managed_shared_memory::segment_manager>StrAllocator;
typedef Employee Value;
typedef std::pair<StrAllocator, Employee> ValueType;
typedef allocator<ValueType, managed_shared_memory::segment_manager>ShMemAllocator; typedef map<StrAllocator, Value, std::less<StrAllocator>, ShMemAllocator> MyMap;


Is this correct?
Thank you very much again...

Dann

Steven Watanabe

unread,
Feb 1, 2010, 10:07:26 PM2/1/10
to boost...@lists.boost.org
AMDG

Daniel Veneros wrote:
> And what about the class?
>

Oh, I see.

> class Employee {
> private:
> string name;
> int age;
>
> public:
> Employee();
> ~Employee();
> };

The string inside the class needs to use an allocator too.

Everything that allocates memory which you store in
shared memory needs to use the right allocator.

Steven Watanabe

unread,
Feb 3, 2010, 10:24:39 AM2/3/10
to Daniel Veneros, boost...@lists.boost.org
AMDG

Daniel Veneros wrote:
> Thanks,
>
> I fixed some things and its running now.
> What I don't know how to do is to declarate/allocate a custom class..
> I got this:
>
> typedef managed_shared_memory::segment_manager SegmentManager;
>
> typedef allocator<char, SegmentManager> CharAllocator;
>
> typedef basic_string<char, std::char_traits<char>, CharAllocator>
> BasicString;
>
> typedef allocator<int, SegmentManager> IntAllocator;
>
>
> class Action
> {
> int id;
> BasicString task;
> public:
> Action(int num, const char *name, const VoidAllocator &void_alloc)
> :id(num), task(name,void_alloc)
> {}
> void setId(int num);
> void setTask(BasicString newTask);
> };
>
> void Action::setId(int num) {
> id = num;
> }
>
> void Action::setTask(BasicString newTask) {
> task = newTask;
> }
>
>
> Now... how should I allocate the "Class" object??
> Any Idea? Thanks!!
>

I assume that by Class you mean the Action class?
If this class is used at the top level, you can use
managed_shared_memory::construct. If you want
to use an allocator with it, the commands are

allocator<Action, SegmentManager> alloc(...);
// allocate memory
Action* action = alloc.allocate(1);
// construct an object using placement new
new (action) Action(12, "action", ...);

In Christ,
Steven Watanabe

P.S. Please send messages like this to boost-users rather than directly
to me.

Daniel Veneros

unread,
Feb 4, 2010, 2:38:12 PM2/4/10
to boost...@lists.boost.org
Hi, thanks for all the help, everything is working perfect now.
I have another question, I need to access the shared memory segment from several process and all at the same time. I tried to use pthreads but that didn't work.
I was looking at boost::interprocess threads but I'm not sure how to implement the mutex.
this is the code I have:

#include <boost/interprocess/managed_shared_memory.hpp>

#include <boost/interprocess/containers/vector.hpp>

#include <boost/interprocess/containers/string.hpp>

#include <boost/interprocess/containers/map.hpp>

#include <boost/interprocess/allocators/allocator.hpp>

#include <cstdlib>

#include <string>

#include <iostream>

#include <map>

#include <sstream>


using namespace boost::interprocess;

typedef managed_shared_memory::segment_manager SegmentManager;

typedef allocator<void, SegmentManager> VoidAllocator;

typedef allocator<char, SegmentManager> CharAllocator;

typedef basic_string<char, std::char_traits<char>, CharAllocator> BasicString;


class Action

{

    int id;

    BasicString task;

public:

    Action(int num, const char *name, const VoidAllocator &void_alloc)

            :id(num), task(name,void_alloc)

            {}

            void setId(int num);

            void setTask(BasicString newTask);

            int getId();

};

int Action::getId() {

    return id;

}

void Action::setId(int num) {

    id = num;

}

void Action::setTask(BasicString newTask) {

    task = newTask;

}

typedef allocator<Action, SegmentManager> ActionAllocator;

typedef std::pair<const BasicString, Action> MapValueType;

typedef std::pair<BasicString, Action> MovableToMapValueType;

typedef allocator<MapValueType, SegmentManager> MapValueTypeAllocator;

typedef map<BasicString, Action, std::less<BasicString>, MapValueTypeAllocator> MyMap;



int main(int argc, char** argv) {

    //Remove shared memory on construction and destruction

    struct shm_remove {

        shm_remove() {shared_memory_object::remove("MySharedMemory"); }

        ~shm_remove() {shared_memory_object::remove("MySharedMemory"); }

    }remover;

    

    managed_shared_memory segment(create_only, "MySharedMemory", 65536);

    VoidAllocator alloc_inst(segment.get_segment_manager());

   MyMap *myMap = segment.construct<MyMap>("Map")(std::less<BasicString>(),alloc_inst);

    std::string keyword;

    std::string helper;

    int i=0;

    for(int adder = 0; adder<=1000; adder++)

    {

        keyword = "Hello";

        std::stringstream out;

        out << adder;

        helper = out.str();

        keyword = keyword + helper;//Creates a string "Hello" + adder

        BasicString key(keyword.c_str(), alloc_inst);//string to BasicString

        Action action(i,"Hello", alloc_inst);

        MapValueType value(key, action);

        myMap->insert(value);

        i++;

    }

        

How do I have to set the mutex??
Thanks!


Dann
Reply all
Reply to author
Forward
0 new messages