0

I'm having some trouble implementing boost/interprocess library for shared memory operations between two programs. This is the first I've used any shared memory operations, and I have first modified some of the sample code in the boost documentation I found here: (http://www.boost.org/doc/libs/1_41_0/doc/html/interprocess/quick_guide.html).

The modified demo works good, and basically is like this:

typedef std::pair<double, int> MyType;
managed_shared_memory segment(create_only, "MySharedMemory", 65536);

MyType *instance = segment.construct<MyType>
    ("MyType instance")  //name of the object
    (12.34, 0);            //ctor first argument

MyType *instance2 = segment.construct<MyType>
    ("MyType instance2")  //name of the object
    (56.78, 0);            //ctor first argument

And then in a another process, retrieve these variables:

managed_shared_memory segment(open_only, "MySharedMemory");

std::pair<MyType*, managed_shared_memory::size_type> res;
std::pair<MyType*, managed_shared_memory::size_type> res2;

res = segment.find<MyType>("MyType instance");
printf("1: %d, %d\n", res.first, res.second); // show pointer and size
printf("1a: %f\n\n", *res.first); //show double value


res2 = segment.find<MyType>("MyType instance2");
printf("2: %d, %d\n", res2.first, res2.second); // show pointer and size
printf("2a: %f\n", *res2.first); // show double value

ok, so all th at looks ok, and the terminal output is:

1: 196724, 1
1a: 12.340000

2: 196780, 1
2a: 56.780000

The problem is when I try and replicate this in another (existing) application.

I have done everything almost identically as far as I can tell (identically in terms of syntax even maybe?), but am getting some different and unexpected results.

typedef std::pair<double, int> myDouble;
managed_shared_memory segment(create_only, "sharedMemBlock", 65536);

myDouble *valX = segment.construct<myDouble>
    ("valX")
    (1.1, 0);

myDouble *valY = segment.construct<myDouble>
    ("valY")
    (2.2, 0);

myDouble *valZ = segment.construct<myDouble>
    ("valZ")
    (3.3, 0);

and in the second process to retrieve these values:

managed_shared_memory segment(open_only, "sharedMemBlock");
std::pair<myDouble*, managed_shared_memory::size_type> valShrX;
std::pair<myDouble*, managed_shared_memory::size_type> valShrY;
std::pair<myDouble*, managed_shared_memory::size_type> valShrZ;

valShrX = segment.find<myDouble>("valX");
valShrY = segment.find<myDouble>("valY");
valShrZ = segment.find<myDouble>("valZ");

printf("PtrvalSharedX: %d,PtrvalSharedY: %d, PtrvalSharedZ: %d\n", valShrX.first, valShrY.first, valShrZ.first);
printf("valSharedX: %f, valSharedY: %f, valSharedZ: %f\n\n", *valShrX.first, *valShrY.first, *valShrZ.first);

but the results are not what I expect, and are coming out like this:

PtrvalSharedX: 196724, PtrvalSharedY: 196772, PtrvalSharedZ: 196820
valSharedX: 1.100000, valSharedY: 0.000000, valSharedZ: 2.200000

So, what's going on here? Why am I not getting 1.1, 2.2 and 3.3 for valSharedX, valSharedY, and valSharedZ respectively?

Not sure why essentially the same code works in one instance, but not another. I noticed that the difference between pointers in the first example (196780 - 196724) = 56, but is smaller in the second example (196772 - 196724) = (196820 - 196772) = 48. Not sure if that is relevant, but thought it was worth pointing out (pun!).

Thanks, B

brneuro
  • 326
  • 1
  • 5
  • 15
  • 1
    What is `myDouble`? – James Adkison May 26 '16 at 17:27
  • sorry, forgot that line in putting together the excerpt. defined exactly same as MyType was in first example. typedef std::pair myDouble; – brneuro May 26 '16 at 17:36
  • You should [edit](http://stackoverflow.com/posts/37467004/edit) your question to include it now. However, the problem is not immediately obvious when I look at your code and I don't have boost to try it myself. – James Adkison May 26 '16 at 17:42
  • ok.. edited.. also who down-voted the question, and why? hope its not cause I left out typedef of myDouble... no reason I can see why this question should get downvoted. speak up whoever you are! – brneuro May 26 '16 at 20:03
  • Unfortunately there's no way to know who down voted and your comment will likely fall on deaf ears because they'll likely never see it. In case that's a subtle way of asking me, I didn't down vote the question. – James Adkison May 26 '16 at 20:05
  • hah I figured it wasn't you cause we worked out our differences :) its a legit question as far as i can tell, I've done my best at due diligence trying to figure it out msyelf... i'm just calling out whoever the passive aggressive clicker is that is making it harder for me to figure out an answer.. imo, shouldn't be able to vote without contributing to the discussion – brneuro May 26 '16 at 20:09
  • You'll have to find out the difference. As a question this question is **not** viable and certainly not useful to anyone else. So, aggressive as it may be, it's not an unexpected downvote. As a troubleshooting hint: are both processes compiled using the same architecture, flags and versions (e.g. 32-bit vs 64-bit is NOT compatible) – sehe May 26 '16 at 21:13
  • see? right there. it IS a viable question if you have some sort of input, like suggesting there are things to consider other than the code I've posted, like compiler options. If I read somewhere on SO that this would influence the behaviour, I wouldn't have posted this. I would imagine that this info could actually benefit someone else in a useful way, as it would have benefited me if someone else got an answer to a similar question. This site is moderated by closed minded opinions, and privileged users editing questions cause they think they know better, so you're right, its not unexpected. – brneuro May 27 '16 at 12:38
  • I might even go as far as saying that it would be useful if someone could actually suggest what compiler flags would influence the behaviour, since I haven't seen this clearly documented anywhere. Again, I shouldn't have to justify this, but the info could viably help someone else like me who has put together the code while dotting the i's and crossing the t's but would be guessing at what compiler flags might affect the code in a negative way. – brneuro May 27 '16 at 12:39

1 Answers1

0

The problem that everyone overlooked, including myself, was this...

because of the type:

std::pair<myDouble*, managed_shared_memory::size_type> valShrX

getting:

valShrX.first

returns a pointer to a myDouble, and not to the first double that is a part of the std::pair that is defined in:

typedef std::pair<double, int> myDouble;

Since printf doesn't know what myDouble type really is, and since that type is not natively known by printf, the issue presented only when printing multiple values in a sequence and relates to the size of myDouble not matching the size of a double.

So printing each value with its own printf statement (like in the first code excerpt) works fine, because the pointer valShrX.first tells printf where to start correctly. Even though the size of valShrX.first must include the int that is a part of the pair, printf prints the %f and stops.

In the second code excerpt, I tried printing all three values in shared memory in the same printf statement, and so the full size of std::pair myDouble (including therein the double and the int) was propagated and would offset the second and third values printed.

The correct statement should get just the first item of the myDouble pair, that is within the parent pair ... In other words this is the correct printf syntax given my data types:

printf("valSharedX: %f, valSharedY: %f, valSharedZ: %f\n\n", valShrX.first->first, valShrY.first->first, valShrZ.first->first);

So, my printf syntax was incorrect in both examples, but the more punitive operation of printf when printing multiple values in one statement was the only case to make the problem apparent.

My only remaining question that is tickling my brain is this: Why did this problem present itself in Visual Studio 2013, but the identical code when compiled in Linux did not show the problem when printf's %f received a myDouble in a series of values being printed? It all worked fine when compiled in linux. why?

brneuro
  • 326
  • 1
  • 5
  • 15
  • since the boost::interprocess examples demonstrate only putting your data into shared memory, and don't demonstrate getting your data out of shared memory, I would argue this IS relevant for others to see *cough*cough @sehe.... upvotes on my question and answer would be appreciated. – brneuro Jun 01 '16 at 14:18