vector of reference wrapper, push_back failure?

Raph Schim

I have a problem that is giving me trouble; my goal is to create an octree.

Actually, it's very cheap (but it's nearly enough for what I want to do with that octree).

My problem is that my std::vector<std::reference_wrapper<Point>> is filled with the same value. So my insertion creates an infinite loop. But here's the code, maybe it'll be more understandable. I put commentaries where my error occurs.

source.cpp

void main(){
    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_real_distribution<double> uni(0, 2);
    auto random_integer = uni(rng);
    Point firstCenter = Point(1, 1, 1);
    Point firstHalfDimension = Point(1, 1, 1);
    Octree oct(firstCenter, firstHalfDimension);

    for (int i = 0; i < 3; ++i) {
        double x = uni(rng);
        double y = uni(rng);
        double z = uni(rng);
        Point ptmp = Point(x, y, z);
        std::cout << x << " " << y << " " << z << std::endl;
        auto po = std::ref(ptmp);
        oct.insert(po);
    }
}

Octree.hpp

class Octree {
    Node octree;
    Point firstCenter;
    Point firstHalfDimension;

public: 
    Octree() = default;
    Octree( Point& firstCenter, Point& firstHalfDimension) :
        firstCenter(firstCenter), firstHalfDimension(firstHalfDimension), octree(firstCenter, firstHalfDimension) {}

    void insert(std::reference_wrapper<Point> pt) {
        octree.insert(pt);
    }
};

Node.hpp (where the problem occurs)

#define MAXVAL 2
using Point = gmtl::Vec3d;

class Node {
    Point center;
    Point halfDimension;
    std::vector<std::reference_wrapper<Point>> datas;
    std::array<std::shared_ptr<Node>, 8> children;


    int getOctant(const std::reference_wrapper<Point> p) {
        int oct = 0;
        if (p.get()[0] >= center[0]) oct |= 4;
        if (p.get()[1] >= center[1]) oct |= 2;
        if (p.get()[2] >= center[2]) oct |= 1;
        return oct;
    }

    const bool isLeaf()  {
        return !children[0];
    }

public:

    Node(Point center, Point halfDimension) : center(center), halfDimension(halfDimension){
    }
    void insert(const std::reference_wrapper<Point> p) {
        if (isLeaf()){
            if (datas.size() == MAXVAL) { //Must subdivide
                std::cout << p.get()[0] << " " << p.get()[1] << " " << p.get()[2] << std::endl;
                for (int i = 0; i < datas.size(); ++i) {
                    std::cout << datas[i].get()[0] << " "
                        << datas[i].get()[1] << " "
                        << datas[i].get()[2] << std::endl;
 //The problem is here : the vector is filled with the same values, and it's the same value as p. let's say p = (0.4,0.7,0.8), then the for loop will show to the screen : 
 // 0.4 0.7 0.8
 // 0.4 0.7 0.8
 // 0.4 0.7 0.8
                }
                for (int i = 0; i < 8; ++i) {
                    Point newCenter;
                    newCenter[0] += halfDimension[0] * (i & 4 ? .5f : -.5f);
                    newCenter[1] += halfDimension[1] * (i & 2 ? .5f : -.5f);
                    newCenter[2] += halfDimension[2] * (i & 1 ? .5f : -.5f);
                    children[i] = std::make_shared<Node>(newCenter, halfDimension * .5);
                }
                int octant = getOctant(p);
                children[octant]->insert(p);
                for (int i = 0; i < datas.size(); ++i) {
                    int octant = getOctant(datas[i]);
                    children[octant]->insert(datas[i]);
                }


            }
            else { //Just add
                datas.push_back(p);
            }
        }
        else { //Non-leaf node
            children[getOctant(p)]->insert(p);
        }
    }
};

I really don't understand what I'm doing wrong.

David Schwartz
std::vector<std::reference_wrapper<Point>> datas;

Something has to own the objects that this vector contains references to.

You filled your vector with references to objects that no longer exist. It's not clear why you think you need a vector of references, but you shouldn't do something unusual unless you have a very good explanation for why the normal way (a vector of values) won't work for you.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

C++ reference changes when push_back new element to std::vector

From Dev

C++11 member variable of reference type, different behaviour after vector push_back

From Dev

Cant push_back() non copyable object to vector reference C++

From Dev

vector push_back in STL?

From Dev

Vector and push_back() behavior

From Dev

Unable to push_back to vector

From Dev

vector push_back zero into an empty vector

From Dev

push_back a vector of vectors into a vector

From Java

Insert or push_back to end of a std::vector?

From Dev

Implementatnion of std::vector::push_back in MSVC

From Dev

vector::push_back and std::move

From Dev

Why are there two overloads for vector::push_back?

From Dev

string Vector push_back failing in class

From Dev

garbage values for vector push_back

From Dev

push_back new element to vector

From Dev

Implementatnion of std::vector::push_back in MSVC

From Dev

garbage values for vector push_back

From Dev

Vector push_back incredibly slow

From Dev

Vector push_back Array of doubles

From Dev

Push_back variadic function parameters into a vector?

From Dev

c++ push_back() a struct into a vector

From Dev

push_back a pointer to a vector of pointers

From Dev

Pass vector<reference_wrapper<int> > to vector<int>?

From Dev

How to use vector iterators when using vector<>::push_back()

From Dev

Calling std::vector::push_back() is changing previous elements in vector?

From Dev

Calling std::vector::push_back() is changing previous elements in vector?

From Dev

How to use vector iterators when using vector<>::push_back()

From Dev

C++ Vector: push_back Objects vs push_back Pointers performance

From Dev

vector push_back causes assertion error but list push_back works

Related Related

HotTag

Archive