Question

I have the following:

#include <boost\interprocess\mapped_region.hpp>
#include <boost\interprocess\file_mapping.hpp>

using namespace std;

void GetFileContents(const char* FilePath, size_t& size, char* data);

int main(){
    char* data = 0;
    const char* FilePath = "My\\Path\\File";
    size_t size = 0;
    GetFileContents(FilePath, size, data);
    //Now data is incorrect
    return 1;
}

void GetFileContents(const char* FilePath, size_t& size, char* data){
    file_mapping fm(FilePath, read_only);
    mapped_region region(fm, read_only);
    data = static_cast<char*>(region.get_address());
    //data is correct here
    size = region.get_size();
}

Within GetFileContents() data contains the right information. However, after data returns from GetFileContents() it contains nothing. What am I doing wrong?

Also, is there a way to remove the static_cast?

Was it helpful?

Solution

In this function:

void GetFileContents(const char* FilePath, size_t& size, char* data){
    file_mapping fm(FilePath, read_only);
    mapped_region region(fm, read_only);
    data = static_cast<char*>(region.get_address());
    ...
}

fm and region are objects with automatic storage duration, lifetime of which ends when the execution goes out of scope. Using their internals after these objects are destructed yields undefined behavior.

Another problem is that you are actually trying to change the pointer itself, meaning that your function should take char** dataPtr and you should call GetFileContents(FilePath, size, &data);.

But since you are using C++, you should consider using std::string or since you're not working with null-terminated string, std::vector<char> might be more appropriate:

void GetFileContents(const char* FilePath, std::vector<char>& content){
    file_mapping fm(FilePath, read_only);
    mapped_region region(fm, read_only);
    content.resize(region.get_size());
    char* src = static_cast<char*>(region.get_address());
    memcpy(&content[0], src, content.size());
}

OTHER TIPS

The only reason that data is correct at that point is because it is now points to whatever whatever region.get_address() points to. fm and region get destroyed when GetFileContents() returns, since they lose scope.

What you need to do is copy the data from region.get_address() into data.

size = region.get_size()
memcpy(data, region.get_address(), size)

Before that though, you need to either pre-allocate data (e.g. in main) or somehow return data (either actually return it or pass it by reference/pointer) and allocate it in GetFileContents().

Assuming you've allocated data to size_t size before calling GetFileContents, you can do this:

char* GetFileContents(...) {
  ...
  memcpy(data, region.get_address(), size)
  size = region.get_size()
  ...
  return data
}


int main() {
  ...
  size_t fileSize = 1024; //maximum size
  char* data = new char[fileSize];
  GetFileContents("file.dat", fileSize, data)
  // now fileSize is the real file size
  ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top