Trouble initializing pointer to vector of ofVec2f?

This might be a silly question, but I’m having some trouble here. I thought I understood pointers but this is throwing me for a loop.
[ note: I’m using oF 0.8.4 on OSX ]

issue:
I have a Shirt class that stores 3 pointers to 3 vectors that are created by a separate Body class.
Within Shirt, there’s a function that draws the points to screen if they exist. Everything works fine unless the Body class fails to create any of the vectors. In that case, Shirt’s pointer to the vector should be NULL and it shouldn’t draw.

But instead I get a bad access exception in ofVec3f.h at line 258:
inline ofVec3f::ofVec3f( const ofVec2f& vec ):x(vec.x), y(vec.y), z(0) {}

Here’s my Shirt header:

class Shirt {

public:
    
    Shirt();
    
    void updateTorso(vector<ofVec2f>& torsoOutline);
    void updateLArm(vector<ofVec2f>& lArmOutline);
    void updateRArm(vector<ofVec2f>& rArmOutline);
    
    void drawPoints();
    
    vector<ofVec2f>* _torso;
    vector<ofVec2f>* _lArm;
    vector<ofVec2f>* _rArm;
    
};

and my class definition:

#include "Shirt.hpp"

Shirt::Shirt(){
    
    _torso = NULL;
    _lArm = NULL;
    _rArm = NULL;
}

void Shirt::updateTorso(vector<ofVec2f>& torsoOutline){
    _torso = &torsoOutline;
}
void Shirt::updateLArm(vector<ofVec2f>& lArmOutline){
    _lArm = &lArmOutline;
}
void Shirt::updateRArm(vector<ofVec2f>& rArmOutline){
    _rArm = &rArmOutline;
}

void Shirt::drawPoints(){
    
    ofPushStyle();
    
    // torso - blue
    if (_torso){
        ofSetColor(ofColor::blue);
        for (int i=0; i<4; i++){
            ofCircle((*_torso)[i], 3);
        }
    }
    
    // left arm - green
    if (_lArm){
        ofSetColor(ofColor::green);
        for (int i=0; i<4; i++){
            ofCircle((*_lArm)[i], 3);
        }
    }
    
    // right arm - red
    if (_rArm){
        ofSetColor(ofColor::red);
        for (int i=0; i<4; i++){
            ofCircle((*_rArm)[i], 3);
        }
    }

    ofPopStyle();
}

Shouldn’t the if (_lArm) only run if _lArm is pointing to something? That’s where I get the exception (i.e. when I create a torso but no left arm).

have you tried not assigning them to NULL but then checking if(_lArm != nullptr){}

Also I think you need to do this:

myClass{
void updateThing(vector* vectorname);
}

void myClass::updateThing(vector* vectorname){
_internalThing = vectorname;
}

void ofApp::setup(){
myClass classvariable;
classvariable.updateThing( &torsovariable);

}

Thanks, I just tried if (_lArm != nullptr) but it throws an error “use of undeclared identifier ‘nullptr’”

Not sure if this is a compiler thing (I’m using XCode). Is there any other reliable way to check for null pointers?

I suppose I could take out the if statement and instead use:

    for (int i=0; i<_torso->size(); i++){
        ofCircle((*_torso)[i], 3);
    } 

But now I’m interested in knowing how to check for null pointers in general.

Per the second reply, that’s essentially what I have now. ofApp sends references of the Body vectors to Shirt, and Shirt stores pointers to them. The problem is that if I don’t run one of the update functions in Shirt first, my app crashes. There are ways of getting around that of course, but I’d like to know the most universal solution without having to use boolean variables or whatnot.

A related question I have is how to initialize the vector pointers to default vector values (e.g. ofVec2f(0,0) rather than NULL) within the Shirt constructor?

I’ve tried several ways, such as:

Shirt::Shirt(){
    
    _torso = new vector<ofVec2f>(4,ofVec2f(0,0));
    _lArm = new vector<ofVec2f>(4,ofVec2f(0,0));
    _rArm = new vector<ofVec2f>(4,ofVec2f(0,0));
}

and

Shirt::Shirt(){
    
    _torso = new vector<ofVec2f>;
    _lArm = new vector<ofVec2f>;
    _rArm = new vector<ofVec2f>;
    for (int i=0; i<4; i++){
        _torso->push_back(ofVec2f(0,0));
        _lArm->push_back(ofVec2f(0,0));
        _rArm->push_back(ofVec2f(0,0));
    }
}

and

Shirt::Shirt(){
    
    _torso = new vector<ofVec2f>;
    _lArm = new vector<ofVec2f>;
    _rArm = new vector<ofVec2f>;
    _torso->resize(4);
    _lArm->resize(4);
    _rArm->resize(4);
}

all with the same exception at runtime, if I don’t use one of the update functions in Shirt before calling drawPoints()

ofVec3f.h at line 258:
inline ofVec3f::ofVec3f( const ofVec2f& vec ):x(vec.x), y(vec.y), z(0) {}

I’m using C++11 and nulptr exists there, not sure what to do on earlier versions.

Per the second reply, I think that you might be sending the address of a ofVec2f as an argument to your update function, and then taking the address of THAT and storing it into your pointer. A pointer to a pointer

full disclosure: pointers aren’t my strong suite and I’m just telling you what’s worked for me and how I’ve seen other people use pointers. I had a similar problem in a program I was writing and solved it with my suggestion above

Try this Basic app which should be illustrative (it’s how I would do it):

ofApp.h file:

#pragma once

#include "ofMain.h"

class Foo {
public:
    Foo() {
        a = new vector<ofVec2f>();
        b = new vector<ofVec2f>();
        c = new vector<ofVec2f>();
    };
    
    void updateA(vector<ofVec2f>* vals) {
        a = vals;
    };
    void updateB(vector<ofVec2f>* vals) {
        b = vals;
    };
    void updateC(vector<ofVec2f>* vals) {
        c = vals;
    };
    void draw() {
        ofPushStyle();
        ofSetColor(255, 0, 0);
        for(int i = 0; i < a->size(); i++) {
            ofDrawCircle((*a)[i].x, (*a)[i].y, 10);
        }
        ofSetColor(0, 255, 0);
        for(int i = 0; i < b->size(); i++) {
            ofDrawCircle((*b)[i].x, (*b)[i].y, 10);
        }
        ofSetColor(0, 0, 255);
        for(int i = 0; i < c->size(); i++) {
            ofDrawCircle((*c)[i].x, (*c)[i].y, 10);
        }
        ofPopStyle();
    }
    
private:
    vector<ofVec2f>* a;
    vector<ofVec2f>* b;
    vector<ofVec2f>* c;
};

class ofApp : public ofBaseApp{

	public:
		void setup();
		void update();
		void draw();

            Foo iPityTheFoo;
    
            vector<ofVec2f> appA;
            vector<ofVec2f> appB;
            vector<ofVec2f> appC;

};

ofApp.cpp file:
#include “ofApp.h”

//--------------------------------------------------------------
void ofApp::setup(){
    appA.push_back(ofVec2f(50, 50));
    appA.push_back(ofVec2f(100, 50));
    appA.push_back(ofVec2f(150, 50));
    
    appB.push_back(ofVec2f(50, 100));
    appB.push_back(ofVec2f(100, 100));
    appB.push_back(ofVec2f(150, 100));
    
    appC.push_back(ofVec2f(50, 150));
    appC.push_back(ofVec2f(100, 150));
    appC.push_back(ofVec2f(150, 150));
    
    iPityTheFoo.updateA(&appA);
    //iPityTheFoo.updateB(&appB);
    iPityTheFoo.updateC(&appC);

}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){
    iPityTheFoo.draw();
}

What we’re doing here is in the class constructor of Foo we initialize three pointers to vectors of ofVec2fs. There pointers are not null, they actually point to something on the heap. Then we use the update functions to set the pointers equal to other pointers to vector objects which means that when we draw them they will then be the correct values. If we comment out say the updateB line in ofApp.cpp you can see that you receive no exception because the pointer is not null and you’re not trying to access a value that doesn’t exist because when we loop over them we’re looping over them b->size() times instead of a fixed number (in your case 4) so if b is not set b->size() returns 0 so we don’t even try to find any vector elements by index.

In your code you are trying to find the 0th element of an empty vector which is throwing the error.

is that illustrative/helpful at all? If anyone knows a better way do let me know!

Hi,

I think you’ve already got the right syntax to check yours pointers.

OF 8.4.0 don’t use c++11 by default, so nullptr is not available. Don’t know for Mac OS, but with Windows and Code::blocks it is possible to enable c++11 by configuring the project after its creation by the project generator. But you don’t need to do that, you’ve already got the good syntax.

I think the error is here. It should be interesting to have a look at your body class. But in the meantime I see 2 possible scenarios :

Scenario 1 :

Shirt aShirt;
vector< ofVect2f > v;
// here the code which fails to initialize the vector
aShirt.updateTorso( v );

In this case you pass to the shirt an empty vector, and the drawPoints() method must crash, because it doesn’t check the vector bounds. This is why you have to check the vector size. It isn’t a good practise that the Shirt class assume that the user (in this case your body class) call the updateTorso method with a proper vector. What if the vector is empty ? What if its size is 1, or 2, or 3, or 100 ?

Scenario 2 :

Shirt aShirt;
vector< ofVect2f > * v = NULL;
// here the code which fails to initialize the vector
aShirt.updateTorso( *v );

This is undefined behavior. Never deferencing a pointer without being sure that it is actualy pointing to a defined object.
See http://stackoverflow.com/questions/2727834/c-standard-dereferencing-null-pointer-to-get-a-reference
Perhaps it is better, in your case, to code

void updateTorso(vector<ofVec2f>* torsoOutline);

like @sterlingcrispin do, rather than

void updateTorso(vector<ofVec2f>& torsoOutline);

Interesting - Thank you for clarification on the null reference being undefined behavior.

Now that I’m down this rabbit hole (my app is working for my purposes - now I’m just asking to learn better standards since my coding skills are very rag tag):

Is there an alternative way to take in and store a pointer to an external variable within a class… using references?

i.e.

class MyClass {
    MyClass(){}
    ofImage* _img;
    
    void store(ofImage& img) { _img = &img; }
};

Which is what I usually do. I like the simplicity of using reference arguments when implementing the class, but now I’m realizing that this is probably not the right way for a number of reasons (like the null reference issue and this, which I sort of understand). Should I always just pass in pointers if I’m going to save them as pointers?

Hopefully that makes sense. I really appreciate the helpful replies!

I don’t know if it’s a rule. I like to do this because it warn the user about the fact that the class may store the pointer internaly, like you do. Then the user is aware of the fact that he may encounter problems if he modify the pointed object afterward.

I think that in your case, you can just copy the vector. 4 ofVec3f is not a big deal to copy, and you can avoid some troubles later. I prefer to avoid the use of pointers everytime it’s possible.

class Shirt {
public:
    Shirt();
    void updateTorso(const vector<ofVec2f>& torsoOutline);
    void drawPoints();
    vector<ofVec2f> _torso;
};

void Shirt::updateTorso(const vector<ofVec2f>& torsoOutline){
    _torso = torsoOutline;
}

void Shirt::drawPoints(){
    ofPushStyle();
    ofSetColor(ofColor::blue);
    for (int i=0, n=_torso.size(); i<n; ++i){
        ofCircle( _torso[i], 3);
    }
    ofPopStyle();
}

I use const vector< ofVec2f > & because

  • a reference avoid the creation of a temporary copy of the vector when it is received
  • a const reference inform the user that the method don’t modify the vector

If a valid outline must have 4 vertices, another idea is to make a class BodyPartOutline.

class BodyPartOutline {
public:
    ofVec2f p1, p2, p3, p4;
    void drawVertices() {
         ofCircle( p1, 3);
         ofCircle( p2, 3);
         ofCircle( p3, 3);
         ofCircle( p4, 3);
}

class Shirt {
    public:
        Shirt();
        void updateTorso(const BodyPartOutline & torsoOutline);
        void drawPoints();
        Torso _torso;
    };

    void Shirt::updateTorso(const BodyPartOutline & torsoOutline){
        _torso = torsoOutline;
    }

    void Shirt::drawPoints(){
        ofPushStyle();
        ofSetColor(ofColor::blue);
        _torso.drawVertices();
        ofPopStyle();
    }