Handling Huge Multidimensional Arrays in C++

前端 未结 8 1994
别那么骄傲
别那么骄傲 2021-01-24 19:15

I\'m designing a game in C++ similar to Minecraft that holds an enormous amount of terrain data in memory. In general, I want to store an array in memory that is [5][4][5][50][

相关标签:
8条回答
  • 2021-01-24 19:47

    In order to do exactly what you're trying to do you have to declare everything as pointers (and pointers to pointers to pointers to pointers) and then allocate each one individually.

    Teh sux!

    A better option is to simply allocate the ginormous block in one chunk and use multiple variable along with pointer arithmetic to arrive at the correct location.

    Edit: Wasn't paying attention and didn't notice your constructor. That's not only not the way to get your Child allocated on the free-store, it's a great way to create situations eliciting undefined behavior. Your Child will be gone when the constructor is through and the pointer to it will then be invalid. I wonder if you shouldn't run through some basic tutorials before trying to write a game.

    0 讨论(0)
  • 2021-01-24 19:49

    A smaller example (with changed names for all the structs, to make the general principle clearer). The 'Bloe' struct is the one you want to allocate on the heap, and this is accomplished using 'new'.

       struct Bla {
            int arr[4][4];
       };
    
       struct Bloe {
            Bla bla[2][2];
       };
    
       int main()
       {
            Bloe* bloe = new Bloe();
            bloe->bla[1][1].arr[1][1] = 1;
            return 0;
       }
    
    0 讨论(0)
  • 2021-01-24 19:52

    If you want to allocate something on the heap, use new.

    #include <memory>
    
    class Parent
    {
        std::auto_ptr<Child> child; // use auto_ptr for dynamically-allocated members
        Parent(const Parent&); // You probably don't want to copy this giant thing
    public:
        Parent();
    };
    
    Parent::Parent()
      : child(new Child) // initialize members with an initializer list
    {
    }
    

    Also, avoid mixing C and C++ styles. There's no reason to do

    typedef struct blah{ ... } BLAH;
    

    in C++. A struct is just a class with all of the members public by default; just like a class, you can refer to the struct type's name without using the struct tag. There's also no need to specify void for a function that takes no parameters.

    boost::multi_array (linked in PigBen's answer) is a good choice over raw arrays.

    0 讨论(0)
  • 2021-01-24 19:54

    Below is how I understood what you showed you were trying to do in your example. I tried to keep it straightforward. Each Array of [50][50][50] is allocated in one memory chunk on the heap, and only allocated when used. There is also an exemple of access code. No fancy boost or anything special, just basic C++.

    #include <iostream>
    
    class Block
    {
        public:
        // Information about the blocks
        int data;
    };
    
    
    class Grid
    {
        public:
        bool empty;
        Block (*blocks)[50][50];
    
        Grid() : empty(true) {
        }
    
        void makeRoom(){
            this->blocks = new Block[50][50][50];
            this->empty = false;
        }
    
        ~Grid(){
            if (!this->empty){
                delete [] this->blocks;
            }
        }
    };
    
    
    class Parent
    {
        public:
        Grid (* child)[4][5];
    
        Parent()
        {
            this->child = new Grid[5][4][5];
        }
    
        ~Parent()
        {
            delete [] this->child;
        }
    };
    
    
    main(){
        Parent p;
        p.child[0][0][0].makeRoom();
        if (!p.child[0][0][0].empty){
            Block (* grid)[50][50] = p.child[0][0][0].blocks;
            grid[49][49][49].data = 17;
        }
    
        std::cout << "item = " 
                  << p.child[0][0][0].blocks[49][49][49].data 
                  << std::endl;
    }
    

    This could still be more simple and straightfoward and just use one bug array of [50][50][50][5][4][5] blocks in one memory chunk on the heap, but I'll let you figure out how if this is what you want.

    Also, usind dynamic allocation in class Parent only has the sole purpose to use heap instaed of stack, but for such a small array (5*4*5 pointers), allocating it on stack should not be a problem, hence it could be written.

    class Parent
    {
        public:
        Grid child[5][4][5];
    };
    

    without changing anything in the way it is used.

    0 讨论(0)
  • 2021-01-24 20:00

    If you want the class created on the heap, create it with new:

    Child * c = new Child;
    

    and then of course delete it, or better still use a smart pointer.

    0 讨论(0)
  • 2021-01-24 20:03

    Use boost::multi_array

    0 讨论(0)
提交回复
热议问题