Why doesn't managed_shared_memory::find() return the same address as managed_shared_memory::construct()? - boost-interprocess

I'm having a problem where I am using Boost Interprocess to write some values to shared memory using managed_shared_memory::construct() then in another process trying to read those values using managed_shared_memory::find() but it is not coming back with the same address that was created using construct().
I took the sample code from the Boost Interprocess documentation for Creating named shared memory objects and split into two different programs and the same thing is happening.
interprocess_write.cpp
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cstdlib> //std::system
#include <cstddef>
#include <cassert>
#include <iostream>
#include <utility>
int main(int argc, char *argv[])
{
using namespace boost::interprocess;
typedef std::pair<double, int> MyType;
if(argc == 1){ //Parent process
shared_memory_object::remove ("MySharedMemory");
//Construct managed shared memory
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
//Create an object of MyType initialized to {0.0, 0}
MyType *instance = segment.construct<MyType>
("MyType instance") //name of the object
(0.0, 0); //ctor first argument
//Create an array of 10 elements of MyType initialized to {0.0, 0}
MyType *array = segment.construct<MyType>
("MyType array") //name of the object
[10] //number of elements
(0.0, 0); //Same two ctor arguments for all objects
//Create an array of 3 elements of MyType initializing each one
//to a different value {0.0, 0}, {1.0, 1}, {2.0, 2}...
float float_initializer[3] = { 0.0, 1.0, 2.0 };
int int_initializer[3] = { 0, 1, 2 };
MyType *array_it = segment.construct_it<MyType>
("MyType array from it") //name of the object
[3] //number of elements
( &float_initializer[0] //Iterator for the 1st ctor argument
, &int_initializer[0]); //Iterator for the 2nd ctor argument
std::cout << array << ":" << instance << ":" << array_it << std::endl;
//Check child has destroyed all objects
if(segment.find<MyType>("MyType array").first ||
segment.find<MyType>("MyType instance").first ||
segment.find<MyType>("MyType array from it").first)
return 1;
}
return 0;
}
interprocess_read.cpp
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cstdlib> //std::system
#include <cstddef>
#include <cassert>
#include <iostream>
#include <utility>
int main (int argc, char **argv)
{
using namespace boost::interprocess;
typedef std::pair<double, int> MyType;
//Open managed shared memory
managed_shared_memory segment(open_only, "MySharedMemory");
std::pair<MyType*, managed_shared_memory::size_type> res;
//Find the array
res = segment.find<MyType> ("MyType array");
//Length should be 10
if(res.second != 10) return 1;
std::cout << res.first << ":";
//Find the object
res = segment.find<MyType> ("MyType instance");
//Length should be 1
if(res.second != 1) return 1;
std::cout << res.first << ":";
//Find the array constructed from iterators
res = segment.find<MyType> ("MyType array from it");
//Length should be 3
if(res.second != 3) return 1;
std::cout << res.first << std::endl;
//We're done, delete all the objects
segment.destroy<MyType>("MyType array");
segment.destroy<MyType>("MyType instance");
segment.destroy<MyType>("MyType array from it");
}
When I ran the interprocess_write program I got the following output:
0x1260128:0x12600d8:0x1260208
But when I run the interprocess_read program I get:
0x2ad0128:0x2ad00d8:0x2ad0208
Is there something missing that has to be done in interprocess_read to make it pull the correct addresses out of shared memory?

Related

Freeing an array of pointer but heap block

I wrote a program that has to read a 2D array from a text file and save it into a double pointer which will act as a 2D array.
Here's the code :
#include <stdio.h>
#include <stdlib.h>
char **create_map(char* filename);
int n;
int m;
char **map;
int main(int argc, char* argv[]) {
int i;
map = create_map(argv[1]);
for(i = 0; i < n; i++) {
free(map[i]);
}
free(map);
return 0;
}
char **create_map(char *filename) {
int i = 0;
char *row;
char **map;
FILE *file = fopen(filename, "r");
fscanf(file, "%d %d", &n, &m);
map = malloc(sizeof(char *) * n);
row = malloc(sizeof(char)*m);
while(fscanf(file, "%s\n", row) != EOF) {
map[i] = malloc(sizeof(char)*m);
strcpy(map[i], row);
i++;
}
free(map[9]);
free(row);
fclose(file);
return map;
}
The content of the file is stored successfully in the map variable, but when it comes to freeing some space the debugger prints "warning: Heap block at 0000029967AF5770 modified at 0000029967AF578A past requested size of a".
Why the memory can't be freed?
Where's the error?
Thank you in advance.

Converting std::vector from BYTE to int

Code:
using ColumnIndexVector = std::vector<int>;
using ByteVector = std::vector<BYTE>;
void CCreateReportDlg::GetColumnIndexesToExclude()
{
const CString strSection = theApp.GetActiveScheduleSection(_T("Options"));
ByteVector vData = theApp.GetProfileVector(strSection, _T("AssignStatesEx"));
ColumnIndexVector vTemp(vData.begin(), vData.end()); // This converts BYTE to int
m_vColumnIndexesToExclude = vTemp;
}
Is there any way to avoid the requirement for vTemp without manually iterating vData and casting from BYTE to int?
Yes, just use assign(). IDK if you need to use clear() as well, but probably not. Just step through the runtime code the first time to know.
m_vColumnIndexesToExclude.assign(vData.begin(), vData.end());
Here's a test program:
#include <windows.h>
#include <iostream>
#include <vector>
using namespace std;
using ColumnIndexVector = std::vector<int>;
using ByteVector = std::vector<BYTE>;
int main(int argc, char* argv[])
{
cout << "Test" << endl;
ByteVector bytes = {'A', 'B', 'C', 'D'};
ColumnIndexVector colVector;
for ( auto _val: bytes)
{
cout << _val << endl;
}
colVector.assign(bytes.begin(), bytes.end());
for ( auto _val : colVector)
{
cout << _val << endl;
}
return 0;
}

Initializing trough constructor a 2-Dimensional pointer

I have created a class and tried to initialize a 2D pointer in my class constructor. Then I use a getter in my main.cpp but it doesn't worked. Building is successful but I end up with a value 0xcccccccc? when I debug it.
Here is my code.
Header
Asset {
public:
Asset(int numberAssets, int numberReturns); // Constructor
//getter and setter
double **getAssetReturnMatrix();
~Asset();
private:
int _numberAssets, _numberReturns;
double **_assetReturn;
};
Cpp file
#include "Asset.h"
Asset::Asset(int numberAssets, int numberReturns)
{
// store data
_numberAssets = numberAssets; // 83 rows
_numberReturns = numberReturns; // 700 cols
//allocate memory for return matrix
double **_assetReturn = new double*[_numberAssets]; // a matrix to store the return data
for (int i = 0; i<_numberAssets; i++)
_assetReturn[i] = new double[_numberReturns];
}
Asset::~Asset()
{
}
Main.cpp
#include <iostream>
#include "read_data.h"
#include "Asset.h"
using namespace std;
int main(int argc, char *argv[])
{
//Create our class object
int numberAssets = 83;
int numberReturns = 700;
Asset returnMatrix = Asset(numberAssets, numberReturns);
//read the data from the file and store it into the return matrix
string fileName = "asset_returns.csv";
double ** data = returnMatrix.getAssetReturnMatrix();
cout << data; // <--- Value 0xcccccccc? here
//readData(data, fileName);
return 0;
}
Could you please tell me where I am wrong?
Thanks a lot !
I was created a new variable which had nothing to do with my private member double **_assetReturn defined in my h file, here:
//allocate memory for return matrix
double **_assetReturn = new double*[_numberAssets]; // a matrix to store the return data
for (int i = 0; i<_numberAssets; i++)
_assetReturn[i] = new double[_numberReturns];
Changed it to:
//allocate memory for return matrix
this->_assetReturn = new double*[this->_numberAssets]; // a matrix to store the return data
for (int i = 0; i<this->_numberAssets; i++)
this->_assetReturn[i] = new double[this->_numberReturns];
Worked fine now.

Is it possible to have a const reference to a nonconst char pointer?

Is it possible to have a const reference to *argv and iterate through the array of pointers argv?
For the code below, I get the following warning:
a reference of type "const char *& (not const-qualified) cannot be initialized with a value of type "char *"
After building, I get this error message:
cannot convert from 'char *' to 'const char *&'.
#import <iostream>
using std::cout;
using std::endl;
int main (int argc, char * argv []) {
for (const char *& c = *argv; *c != '\0'; ++c) {
cout << *c << endl;
}
return 0;
}
I am confused because I know it is possible to have a const reference to a non-const variable like so:
int i = 42;
int &r1 = i;

Int variable's value won't change after being moved

I've read the basics of move semantics and I did a couple of tests.
Case #1:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string st = "hello";
vector<string> vec;
vec.push_back(st);
cout << st;
cin.get();
}
In this case, the program will not print anything because "hello" has been moved to vector[0].
Case #2:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int num=5;
vector<int> vec;
vec.push_back(num);
cout << num;
cin.get();
}
Why does the program print "5"? I thought num would be 0 or something undefined.
Case #1 should print "hello". If not then your compiler has bug and you should upgrade to a newer version or complain to who ever wrote it.
Case #2 correctly prints "5".
However, if you changed line 10 in case 2 from:
vec.push_back(st);
to:
vec.push_back(std::move(st));
you will get what you expected, a print to console of "" because vector "stole" the value in st.
int is a fundamental type in c++ and trying to "steal" from an int variable doesn't realy work since it does't own any resource.
std::string is a resource owner. It "owns" a char array (this isn't always true, but for simplicity we will pretend it is).
So when we pass std::move(st) to push_back we are calling the T&& overload of push_back which does the "stealing" by calling the move constructor of std::string which releases st's handle and gives it to the newly created std::string inside vec.
But if we called push_back like this: vec.push_back(st); this will not "steal" any thing. Instead, it will call the const T& overload of push_back which just does a simple copy by calling the normal copy constructor of std::string such that we will have st set to "hello" and vec[0] set with its own version of "hello".
Try this code below to see how all this works out:
#include <iostream>
#include <vector>
using namespace std;
struct Foo
{
Foo() // default constructor
{
cout << "Foo()" << endl;
}
Foo(const Foo&) // copy constructor
{
cout << "Foo(const Foo&)" << endl;
}
Foo(Foo&&) // move constructor
{
cout << "Foo(Foo&&)" << endl;
}
Foo& operator=(const Foo&) // copy assignment operator
{
cout << "operator=(const Foo&)" << endl;
return *this;
}
Foo& operator=(Foo&&) // move assignment operator
{
cout << "operator=(Foo&&)" << endl;
return *this;
}
~Foo()
{
cout << "~Foo()" << endl;
}
};
int main()
{
Foo f; // print: Foo();
vector<Foo> vec;
vec.push_back(f); // print: Foo(const Foo&)
vec.push_back(std::move(f)); // print: Foo(Foo&&)
Foo f2; // print: Foo()
f2 = f; // print: operator=(const Foo&)
f2 = std::move(f); // print: operator=(Foo&&)
cin.get();
}

Resources