Search code examples
c++vectorshared-ptr

std::shared_ptr takes lot more memory space than vector


I have a voxel structure as:

struct voxel
{
    unsigned char R, G, B;
    voxel()
    {
        R = G = B = 0;
    }
    //parameteric contructor with parameters
    voxel(unsigned char pR, unsigned char pG, unsigned char pB)
    {
        R = pR; G = pG; B = pB;
    }
};

I have a very large n for number of voxels.

int n = 300 * 300 * 300;

Now when i initialize voxels with vector it takes approximately 79 MB in RAM.

std::vector< voxel > vi(n);

But it takes more than 2 GB when i initialize it this way using shared_ptr and stack overflows.

std::vector< std::shared_ptr<voxel> > vi(n);
for (size_t i = 0; i < n; i++)
{
    vi.push_back(std::shared_ptr<voxel>(new voxel()));
}

What could be the reason for this behavior and how can i avoid it?

Additional Notes:

std::vector< std::shared_ptr<voxel> > vi(n); //statement takes 211 MB alone

Update: I have also tried with this loop instead of push back but the result is same. I now have a general gist of why is this happening.

for (size_t i = 0; i < n; i++)
    {
        vi[i].reset(new voxel());
        vi[i]->B = 0;
        vi[i]->R = 0;
        vi[i]->G = 0;
    }

Solution

  • std::vector< voxel > vi(n);
    

    Is going to take up sizeof(voxel) * n bytes of memory. When you change to a shared pointer you are now going to have the cost of the shared pointer and the the voxel. That would be equivilent to

    sizeof(voxel) * n + sizeof(std::shared_ptr<voxel>) * n
    

    Where the sizeof(std::shared_ptr<voxel>) is likely to be 16 bytes.

    You are also wasting a lot of space in your second example as you declare

    std::vector< std::shared_ptr<voxel> > vi(n);
    

    Which is going to create n empty shared_ptrs and then you push_back another n non empty shared_ptrs so you doulbe the size of the vector. If you want to preallocate the size of the vector then you should use

    std::vector< std::shared_ptr<voxel> > vi;
    vi.reserve(n);