Segfault when trying to access function of member in a library - c++

I have a library that is all tested thoroughly through google test suite. I am trying to keep it "pimpl" clean, but I'm running into a segfault I can't quite figure out.
Relevant Code:
Interface.h:
class Interface{
public:
Interface();
void Function(const int argument);
private:
std::unique_ptr<Implementation> Implement;
std::unique_ptr<DependencyInjection> Injection1, Injection2;
};
Interface.cpp:
Interface::Interface()
: Injection1(new DependencyInjection()),
Injection2(new DependencyInjection()),
Implement(new Implementation(*Injection1, *Injection2)) {}
void Interface::Function(const int argument){ Implement->Function(argument); }
Implementation.h:
class Implementation{
public:
Implementation(AbstractInjection &injection1, AbstractInjection &injection2);
void Function(const int argument);
private:
AbstractInjection Injection1, Injection2;
};
Implementation.cpp
Implementation::Implementation(AbstractInjection &injection1, AbstractInjection &injection2)
: Injection1(injection1),
Injection2(injection2) {}
void Implementation::Function(const int argument){
injection1.Function(argument); } // code from here out is all well tested and works
So when I create the interface and call Interface.Function() the code segfaults when it tries to evaluate Implementation.Function(). I've ran gdb through everything I can think of, all the pointers are non-null.
If I just create a test that looks like
std::unique_ptr<DependencyInjection1> injection1(new DependencyInjection());
std::unique_ptr<DependencyInjection2> injection2(new DependencyInjection());
std::unique_ptr<Implementation> implement(new Implementation(*injection1, *injection2));
implement->Function(0);
The code works fine and does not segfault
But if I create a test like
Interface iface;
iface.Function(0);
it will segfault.
I am new to the whole unique_ptr thing, but I have a suspicion that isn't the larger problem. It may be a red herring, I don't know.

The problem should actually pop as as a warning.
Initializers are done in the order in which they appear in the class definition, not in which they appear in the constructor!
Switch it to:
class Interface{
public:
Interface();
void Function(const int argument);
private:
std::unique_ptr<DependencyInjection> Injection1, Injection2;
std::unique_ptr<Implementation> Implement;
};
From here: C++: Initialization Order of Class Data Members, this is "12.6.2 of the C++ Standard"

You've got a wrong order of member fields, they are initialized in order they are declared in the class. So implement is initialized before both injections. Use -Werror=reorder to get compiler error (for GCC and probably CLang)

Related

C++ Compile time check if a function called before another one

Lets say I have a class with two member functions.
class Dummy {
public:
void procedure_1();
void procedure_2();
};
At compile time, I want to be sure that, procedure_1 is called before procedure_2. What is the correct way do implement this?
Maybe you could do it with a proxy-class. The idea is, that procedure_2 can't be accessed directly from outside (for example by making it private). procedure_1 would return some kind of proxy that allows the access to procedure_2.
Some code below, allthough I don't consider it clean or safe. And if you want, you can still break the system.
IMO such requirements should be handled without explicit validation, because it's quite cumbersome and impossible to make it absolutely safe.
Instead, the dependency should be well documented, which also seems idiomatic in C++. You get a warning that bad things might happen if a function is used incorrectly, but nothing prevents you from shooting your own leg.
class Dummy {
private:
void procedure_2() { }
class DummyProxy
{
private:
Dummy *parent; // Maybe use something safer here
public:
DummyProxy(Dummy *parent): parent(parent) {}
void procedure_2() { this->parent->procedure_2(); }
};
public:
[[nodiscard]] DummyProxy procedure_1() {
return DummyProxy{this};
}
};
int main()
{
Dummy d;
// d.procedure_2(); error: private within this context
auto proxy = d.procedure_1(); // You need to get the proxy first
proxy.procedure_2(); // Then
// But you can still break the system:
Dummy d2;
decltype(d2.procedure_1()) x(&d2); // only decltype, function is not actually called
d2.procedure_2(); // ooops, procedure_1 wasn't called for d2
}
Instead of "checking" it, just do not allow it. Do not expose an interface that allows to call it in any other way. Expose an interface that allows to only call it in specified order. For example:
// library.c
class Dummy {
private:
void procedure_1();
void procedure_2();
public:
void call_Dummy_prodedure_1_then_something_then_produre_2(std::function<void()> f){
procedure_1();
f();
procedure_2();
}
};
You could also make procedure_2 be called from destructor and procedure_1 from a constructor.
#include <memory>
struct Dummy {
private:
void procedure_1();
void procedure_2();
public:
struct Procedures {
Dummy& d;
Procedures(Dummy& d) : d(d) { d.procedure_1(); }
~Procedures() { d.procedure_2(); }
};
// just a simple example with unique_ptr
std::unique_ptr<Dummy::Procedures> call_Dummy_prodedure_1_then_produre_2(){
return std::make_unique<Dummy::Procedures>(*this);
}
};
int main() {
Dummy d;
auto call = d.call_Dummy_prodedure_1_then_produre_2();
call.reset(); // yay!
}
The above are methods that will make sure that inside one translation unit the calls will be ordered. To check between multiple source files, generate the final executable, then write a tool that will go through the generated assembly and if there are two or more calls to that call_Dummy_prodedure_1_then_produre_2 function that tool will error. For that, additional work is needed to make sure that call_Dummy_prodedure_1_then_produre_2 can't be optimized by the compiler.
But you could create a header that could only be included by one translation unit:
// dummy.h
int some_global_variable_with_initialization = 0;
struct Dummy {
....
};
and expose the interface from above into Dummy or add only the wrapper declaration in that library. That way, if multiple souce files include dummy.h, linker will error with multiple definitions error.
As for checking, you can make prodedure_1 and procedure_2 some macros that will expand to something that can't be optimized by the compiler with some mark, like assembly comment. Then you may go through generated executable with a custom tool that will check that the call to prodedure_1 comes before procedure_2.

Compilation error Friend class unable to access field

I am trying to compile QT5.3
The files in question are qv4executableallocator_p.h and qv4executableallocator.cpp. Relevant code snippet from the header is below
struct Allocation{
Allocation()
: addr(0)
, size(0)
, free(true)
, next(0)
, prev(0)
{}
void *start() const;
void invalidate() { addr = 0; }
bool isValid() const { return addr != 0; }
void deallocate(ExecutableAllocator *allocator);
private:
~Allocation() {}
friend class ExecutableAllocator;
Allocation *split(size_t dividingSize);
bool mergeNext(ExecutableAllocator *allocator);
bool mergePrevious(ExecutableAllocator *allocator);
quintptr addr;
uint size : 31; // More than 2GB of function code? nah :)
uint free : 1;
Allocation *next;
Allocation *prev;
};
In the cpp function ExecutableAllocator::ChunkOfPages::~ChunkOfPages() I get a compilation error when trying to access alloc->next.
QV4::ExecutableAllocator::Allocation* QV4::ExecutableAllocator::Allocation::next’ is private
Code can be seen online at https://qt.gitorious.org/qt/qtdeclarative/source/be6c91acc3ee5ebb8336b9e79df195662ac11788:src/qml/jsruntime
My gcc version is relatively old... 4.1
Is this the issue or is something else wrong in my environment. I would like a way to go forward. I am stuck with this compiler, since it is the one I have to use on my target platform
I'd guess that the QV4::ExecutableAllocator::ChunkOfPages struct is not directly befriended with Allocation, so you can't access Allocation's private data in its destructor in C++ prior to C++11 standard.
Try adding friend struct ExecutableAllocator::ChunkOfPages to the Allocation definition, that should do the trick.
There was a slight change in the way nested classes are handled in C++11 (cited from cppreference.com):
Prior C++11, member declarations and definitions inside the nested class of the friend of class T cannot access the private and protected members of class T, but some compilers accept it even in pre-C++11 mode.
Which could explain why this worked in a new compiler, but not in your old one.

c++ class circular reference?

I am working on a little game engine but I got stuck at something. Explanation : I have two classes, cEntity And ObjectFactory :
cEntity
class cEntity:public cEntityProperty
{
Vector2 position;
Vector2 scale;
public:
cEntity(void);
cEntity(const cEntity&);
~cEntity(void);
public:
void init();
void render();
void update();
void release();
};
ObjectFactory
#include "cEntity.h"
#include <vector>
class ObjectFactory
{
static std::vector<cEntity> *entityList;
static int i, j;
public:
static void addEntity(cEntity entity) {
entityList->push_back(entity);
}
private:
ObjectFactory(void);
~ObjectFactory(void);
};
std::vector<cEntity> *ObjectFactory::entityList = new std::vector<cEntity>();
Now I am adding new cEnity to ObjectFactory in cEntity constructor but facing an error related to circular references: for using ObjectFactor::addEntity() I need to define the ObjectFactory.h in cEntity class but it creates a circular reference.
I think your code might have an underlying architectural issue given how you have described the problem.
Your ObjectFactory should be handling the cEntities, which in turn should be unaware of the "level above". From the description of the problem you are having, it implies that you're not sure what class is in charge of what job.
Your cEntitys should expose an interface (i.e. all the stuff marked "public" in a class) that other bits of code interact with. Your ObjectFactory (which is a bit badly named if doing this job, but whatever) should in turn use that interface. The cEntitys shouldn't care who is using the interface: they have one job to do, and they do it. The ObjectFactory should have one job to do that requires it to keep a list of cEntitys around. You don't edit std::string when you use it elsewhere: why is your class any different?
That being said, there's two parts to resolving circular dependencies (beyond "Don't create code that has circular dependencies in the first place" - see the first part to this answer. That's the best way to avoid this sort of problem in my opinion)
1) Include guards. Do something like this to each header (.h) file:
#ifndef CENTITY_H
#define CENTITY_H
class cEntity:public cEntityProperty
{
Vector2 position;
Vector2 scale;
public:
cEntity(void);
cEntity(const cEntity&);
~cEntity(void);
public:
void init();
void render();
void update();
void release();
};
#endif
What this does:
The first time your file is included, CENTITY_H is not defined. The ifndef macro is thus true, and moves to the next line (defining CENTITY_H), before it moves onto the rest of your header.
The second time (and all future times), CENTITY_H is defined, so the ifndef macro skips straight to the endif, skipping your header. Subsequently, your header code only ever ends up in your compiled program once. If you want more details, try looking up how the Linker process.
2) Forward-declaration of your classes.
If ClassA needs a member of type ClassB, and ClassB needs a member of type ClassA you have a problem: neither class knows how much memory it needs to be allocated because it's dependant on another class containing itself.
The solution is that you have a pointer to the other class. Pointers are a fixed and known size by the compiler, so we don't have a problem. We do, however, need to tell the compiler to not worry too much if it runs into a symbol (class name) that we haven't previously defined yet, so we just add class Whatever; before we start using it.
In your case, change cEntity instances to pointers, and forward-declare the class at the start. You are now able to freely use ObjectFactory in cEntity.
#include "cEntity.h"
#include <vector>
class cEntity; // Compiler knows that we'll totally define this later, if we haven't already
class ObjectFactory
{
static std::vector<cEntity*> *entityList; // vector of pointers
static int i, j;
public:
static void addEntity(cEntity* entity) {
entityList->push_back(entity);
}
// Equally valid would be:
// static void addEntity(cEntity entity) {
// entityList->push_back(&entity);}
// (in both cases, you're pushing an address onto the vector.)
// Function arguments don't matter when the class is trying to work out how big it is in memory
private:
ObjectFactory(void);
~ObjectFactory(void);
};
std::vector<cEntity*> *ObjectFactory::entityList = new std::vector<cEntity*>();

undefined reference in pure virtual function C++

I am having some difficulties with a c++ program that I need to run. The problem itself is not mine and I have to make it compile. The algorithm is pretty huge so for my current error message I will demonstrate a much more simplified version of a code that I produced that gives me the exact same error. Here is the code:
class_1.h (class_1.cpp is empty)
class class_1 {
public:
class_1();
virtual ~class_1();
virtual void function() =0;
};
class_2.h (class_2.cpp is empty)
include"class_1.h";
class class_2 : public class_1{
public:
class_2();
virtual ~class_2();
virtual void function();
};
class_2a.h (class_2a.cpp is empty)
include"class_2.h";
class class_2a : public flos2{
public:
class_2a();
virtual ~class_2a();
};
class_3.h
include "class_2a.h"
include "class_1.h" //I tried unsuccesfully without including class_1.h as well
class class_3 {
public:
class_3();
virtual ~class_3();
virtual void function();
private:
class_2a my_class_2a;
};
class_3.cpp
#include "class_3.h"
class_3::class_3()
:my_class_2a()
{
}
class_3::~class_3()
{
this->function();
}
void flos3::function()
{
my_class_2a.function();
/***Main Body of function***/
}
};
The error I am getting is linker error:
undefined reference to `class_2::function()'
I know that in general the whole algorithm seems to be stupid, but more or less this is the what I was given and I am not allowed to change the structure itself, just to make it working. As you can see in class_1 function is defined as a pure virtual function, and then is called through the other classes. I really don't know how to make this thing work, so any help would be really appreciated...
You need to add:
class_1.cpp:
class_1::~class_1() = default;
class_2.cpp:
class_2::~class_2() = default;
void class_2::function() {
// add code here (or not)
}
... and so on.
You are getting linker error because your function class_2::function() does not have implementation. You need to add it, preferably in class_2.cpp file.
void class_2::function()
{
// Implementation goes here
}
Similar problem is with all virtual destructors. They need implementations as well.

Public struct inside c++ class

I'm trying to define a public struct inside a C++ class, and can't figure out how to make it compile. In my header, I have the following:
class AtomUtility
{
public:
struct BoundingBox;
void doWork(struct AtomUtility::BoundingBox bounds);
};
And in the source:
#include"AtomUtility.h"
struct AtomUtility::BoundingBox
{
double xMin, xMax;
};
int main()
{
AtomUtility::BoundingBox *myBox = new AtomUtility::BoundingBox;
myBox->xMin = 0;
myBox->xMax = 10;
AtomUtility *myUtility = new AtomUtility;
myUtility->doWork(*myBox);
delete myUtility;
}
void AtomUtility::doWork(struct AtomUtilty::BoundingBox bounds)
{
//do things...
}
When I attempt to compile this, I get an error: "class "AtomUtility" has no tag member named "BoundingBox".
You've missed the semi-colon after the definition of AtomUtility::BoundingBox and your compiler is getting confused and giving a poor diagnostic.
You're also trying to pass a AtomUtility::BoundingBox* to a function expecting a AtomUtility::BoundingBox
If your compiler gives poor diagnostics it's often useful to try your code on a different compiler. Several are available online, e.g. Comeau, Clang, or a pastebin that compiles, such as http://codepad.org
Quoting https://stackoverflow.com/a/6368118/1483826:
you can only declare pointer or reference to the later class (...). You cannot have objects of later class.
To fix this, you'd need to declare the struct before the class using it as a field.