Read acces violation

I have one class (MetaSystem) that has a getter that returns an instance of another class (System). I want to call system.output() from ofApp, but it returns the error: read access violation. It’s a bit tricky because this function has been assigned with a setter using a function<>. It’s easier to understand with the code:

This is a working example using just C++: https://onlinegdb.com/FKboko-kR

And this is the code in OpenFrameworks that’s not working. In the future I want to call system.output() from ofApp::Draw(), but now I’m doing it from ofApp::setup() just to simplify.

ofApp.h:

#pragma once

#include "ofMain.h"
#include "Syst.h"
#include "MetaSystem.h"
#include <iostream>

class ofApp : public ofBaseApp {
    using Seed = float;

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

    MetaSystem metaSystem;
};

ofApp.cpp

#include "ofApp.h"

void ofApp::setup(){
	metaSystem = MetaSystem();
	std::function<void(Seed)> tempMetaOutput = [](Seed x) {
		cout << "hi" << endl;
	};
	metaSystem.setMetaOutput(tempMetaOutput);

	Syst system = metaSystem.getSystem(10.f);
	system.output(); // This is the function causing the error!
}

MetaSystem.h:

#pragma once
#include <functional>
#include "ofMain.h"
#include "./Syst.h"

class MetaSystem {

public:
	using Seed = float;

	MetaSystem(){ }

	inline void setMetaOutput(std::function<void(Seed)>& _metaOutput) { metaOutput = _metaOutput; }

	Syst getSystem(Seed seed){
		Syst system = Syst();
		system.setMetaOutput(metaOutput);
		system.setInput(seed);
        //system.output() This would work!
		return system;
	}

	std::function<void(Seed)> metaOutput;
};

System.h:

#pragma once
#include "ofMain.h"

class Syst {
public:
    using Seed = float;

    std::function<void()> output;

    Syst() { 
        output = [&]() {
            metaOutput(seed); 
        }; 
    }

    inline void setMetaOutput(std::function<void(Seed)>& _metaOutput) {  metaOutput = _metaOutput; }

    inline void setInput(Seed _seed) { seed = _seed; }

    std::function<void(Seed)> metaOutput;
    Seed seed;
};

Hi @Pau_Rosello , I think this problem is similar to this previous one. It seems like a class with members of std::function need to be constructed in a simple way. Statements like Syst system = Syst(); caused me some problems, and this method may involve multiple calls to a constructor along with a default operator=() for the class. But, creating an object and then setting up its members worked pretty well:

// create an empty Syst; default constructor is called 1 time
Syst system;
// do stuff to set it up
system.setMetaOutput(metaOutput);
system.setInput(seed);

In the following project, Syst and MetaSystem are two distinct classes. You could also have Syst inherit from MetaSystem, as the two classes are related. I deleted MetaSystem::getSystem() and replaced it with Syst::setupFromMetaSystem(). There are various ways to specify Syst::output() too; I gave it a const value in the class declaration.

ofApp.h:

#pragma once
#include "ofMain.h"

class MetaSystem {
public:
    using Seed = float;

    inline void setMetaOutput(std::function<void(Seed)>& _metaOutput) {metaOutput = _metaOutput;}

    std::function<void(Seed)> metaOutput;
};

class Syst {
public:
    using Seed = float;

    // no need to specify any constructor; the compiler will supply a default one

    inline void setMetaOutput(std::function<void(Seed)>& _metaOutput) {metaOutput = _metaOutput;}
    inline void setSeed(Seed _seed) {seed = _seed;}
    void setupFromMetaSystem(MetaSystem& metaSys, Seed s) {
        metaOutput = metaSys.metaOutput;
        seed = s;
    }

    std::function<void(Seed)> metaOutput;
    Seed seed;
    const std::function<void()> output = [this](){metaOutput(seed);};
};

class ofApp : public ofBaseApp{
    using Seed = float;

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

    MetaSystem metaSystem;
    float seedValue;
};

ofApp.cpp:

#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){

    seedValue = 0.0;

    std::function<void(Seed)> tempMetaOutput = [](Seed x){ofDrawBitmapString("seed: " + ofToString(x), ofGetWidth() / 2.f, ofGetHeight() / 2.f);};
    metaSystem.setMetaOutput(tempMetaOutput);

    Syst system;
    system.setupFromMetaSystem(metaSystem, 10.f);
    system.output();
}
//--------------------------------------------------------------
void ofApp::update(){
}
//--------------------------------------------------------------
void ofApp::draw(){
    seedValue += 0.01f;

    Syst system;
    system.setupFromMetaSystem(metaSystem, seedValue);
    system.output();
}
1 Like

Thank you Tim! You solved the issue, and I learned a lot!

But isn’t it a problem to work with arrays or vectors?

Well @Pau_Rosello , I played around with it a bit more, and got back to something very close to your original code, which compiles and runs just fine. I’ll let you parse thru it to see if there are any major differences.

A reference for std::function describes it as copy-constructible and copy-assignable, so doing things like Syst system = Syst(); should be just fine. There is also a note about using a lambda as an argument for a std::function, which might be relevant. I wish I understood this stuff better; there are always things to learn with c++.

ofApp.h:

#pragma once
#include "ofMain.h"
//--------------------------------------------------------------
class Syst {
public:
    using Seed = float;

    Syst(){output = [this](){metaOutput(seed);};}

    inline void setMetaOutput(std::function<void(Seed)>& _metaOutput) {metaOutput = _metaOutput;}
    inline void setSeed(Seed _seed) {seed = _seed;}

    std::function<void(Seed)> metaOutput;
    Seed seed;
    std::function<void()> output;
};
//--------------------------------------------------------------
class MetaSystem {
public:
    using Seed = float;

    inline void setMetaOutput(std::function<void(Seed)>& _metaOutput) {metaOutput = _metaOutput;}

    Syst getSystem(Seed seed){
            Syst system = Syst();
            system.setMetaOutput(metaOutput);
            system.setSeed(seed);
            //system.output() This would work!
            return system;
    }

    std::function<void(Seed)> metaOutput;
};
//--------------------------------------------------------------
class ofApp : public ofBaseApp{
    using Seed = float;

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

    MetaSystem metaSystem;
    float seedValue;
};

ofApp.cpp:

#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){

    seedValue = 0.0;

    std::function<void(Seed)> tempMetaOutput = [](Seed x){ofDrawBitmapString("seed: " + ofToString(x), ofGetWidth() / 2.f, ofGetHeight() / 2.f);};
    metaSystem.setMetaOutput(tempMetaOutput);

    Syst system = metaSystem.getSystem(seedValue);
    system.output();
}
//--------------------------------------------------------------
void ofApp::update(){
}
//--------------------------------------------------------------
void ofApp::draw(){
    seedValue += 0.01f;

    Syst system = metaSystem.getSystem(seedValue);
    system.output();
}

Is this last version working for you? I get an error:

Yeah it compiles and runs. I copied it from the forum into a new project just to make sure. But, this doesn’t mean that there isn’t some undefined behavior going on somewhere. If the previous version works, that may help narrow down real issue. I’m on linux with Qt Creator and GCC just fyi.