开发者

segfault when using mmap

I'm trying to use mmap fo开发者_开发问答r the first time to store a tree object with a lot of data in it. The tree class basically contains a pointer to the root of class Node, and each Node instance has an array of pointers to it's children. I think mmap is doing what it is supposed to, because I can access the tree's constant members, but when I try to access the pointer to the root I get a segfault.

Here is how a create a tree with a root node:

int main(int argc, char *argv[])
{
    Tree *map;
    ...
    map = (Tree*)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (map == MAP_FAILED) {
        close(fd);
        perror("Error mmapping the file");
        exit(EXIT_FAILURE);
    }


    Node* root = new Node("data");
    map->set_root(root);
        ...
}

Here is how I access the Tree:

int main(int argc, char *argv[])
{
    int i;
    int fd;
    Tree *map;

    fd = open(FILEPATH, O_RDONLY);
    if (fd == -1) {
        perror("Error opening file for reading");
        exit(EXIT_FAILURE);
    }

    map = (Tree*)mmap(0, FILESIZE, PROT_READ, MAP_SHARED, fd, 0);

    if (map == MAP_FAILED) {
       close(fd);
       perror("Error mmapping the file");
       exit(EXIT_FAILURE);
    }

    Node* root = map->root();
    cout << root->data();
    ...

The output of root->data() provides a segfault. Can anyone give me a hint to where I'm wrong? Please say if I'm not making my problem clear.

Thanks in advance.

Mads


This is a mess. You need to understand how new and delete work before attempting what you are trying to do.

Where to start.

  1. map = (Tree*)mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); This just says, treat that bit of memory as if it is a Tree, you've not constructed a tree in that bit of memory.
  2. When you call new, it allocates a Node object, somewhere in memory and you hold a pointer to that in your tree, when it is re-opened elsewhere, the pointer is no longer valid.

You need to store all the nodes in your mapped block too... There is no real easy answer to this, except try to understand custom memory allocators.


When you call mmap(), you are basically just getting a block of raw memory. Thus you can't naively dereference the pointer map without invoking some type of undefined behavior ... simply casting the memory returned from mmap() to type Tree* like you've done does not actually construct a Tree object in the mapped memory.

If you wish to construct, or even copy construct a Tree object in the memory returned from mmap, you may want to look into using placement new. For instance, you could do something like the following:

void* map;
map = mmap(0, FILESIZE, PROT_READ, MAP_SHARED, fd, 0);

//...error checking

Tree* tree = new(map) Tree(); //placement new syntax

That will actually default-construct a Tree object in the memory returned from mmap, and at that point, you can properly use the tree pointer variable in order to further add nodes to the tree. For instance, the following code could now be invoked without creating undefined behavior:

Node* root = new Node("data");
tree->set_root(root);

With placement new, an actual Tree object is being pointed to by the variable tree, and you can now properly dereference that pointer, as well as any methods associated with that object.

One major item to keep in mind though is that when using placement new, you will have to manually call the destructor for your Tree object, and you will have to manually free the memory that you've allocated via mmap() ... you can't call delete on the Tree*.


This won't work. If root() is a virtual method, you are hosed, as the vtable pointers point to methods in the current process. It might work if you don't call any virtual methods, but it's probably undefined behavior.

It's probably better to share data between processes, rather than objects. Let the objects have a handle to the data, and shield the user of the object from the details of decoding the data. Node* root = new Tree(memory_mapped_memory);

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜