I'm getting a segfault on line 15 of my .cpp file. I'm not sure why. Various code snippets:
explosionhandler.h:
class explosionhandler {
public:
struct explosion {
...
};
vector<struct explosion> explosions;
struct explosion_type {
...
};
vector<struct explosion_type> type;
int num_types;
explosionhandler();
~explosionhandler();
void registerexplosion(int& ttype,ALLEGRO_BITMAP*& b,int seq, float a, float m,float e);
void createexplosion(int ttype,float x,float y);
void drawexplosions(ALLEGRO_BITMAP* screen);
void gettype(explosion_type& a,ALLEGRO_BITMAP*& b,int& nseq, float& aa, float& ee, float& mm);
};#endif
explosionhandler.cpp:
explosionhandler::explosionhandler()
{
num_types=0;
}
void explosionhandler::registerexplosion(int& ttype,ALLEGRO_BITMAP*& b,int seq, float a, float m,float e)
{
explosion_type n;
....
ttype = num_types; /*********** right here *******************/
num_types++;
type.push_back(n);
}
explosionhandler passed as pointer to object rocket:
rocket.h:
...
class explosionhandler;
class rocket {
public:
...
void setrocket(ALLEGRO_BITMAP*& a,ALLEGRO_BITMAP*& b, explosionhandler*& h);
...
int exptype;
...
}; #endif
rocket.cpp:
rocket::rocket()
{
...
exptype=-1;
}
void rocket::setrocket(ALLEGRO_BITMAP*& a,ALLEGRO_BITMAP*& b, explosionhandler*& h)
{
handler = h;
area.sethitboundaries(a);
fprintf(stdout,"setrocket, # of rockets in vector: %i\n",(int)rockets.size());
h->registerexplosion(exptype,b,3,(float)al_get_bitmap_width(b),(float)0,(float)-18); //called function
}
and finally main.cpp (abbreviated):
#include "rocket.h"
#include "explosionhandler.h"
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <stdio.h>
#include <cstdlib>
#define PI 3.14159265
...
rocket rock(bullet_speed+2,width,height);
explosionhandler *handler;
...
int setup()
{
...
rock.setrocket(rk,exp,handler);
rock.setlimit(5);
al_set_target_bitmap(al_get_backbuffer(display));
...
}
...
Ok Yeah its clear now the problem was handler was not initialized. whoops.
and of course explosionhandler is a pointer in main.cpp, rocket is an object declared in main.cpp, both are globals.
Bless my little noob heart I know not what I do.
My psychic sense tells me that you're calling rocket::setrocket with a NULL pointer as the parameter h (or more specifically, a reference to a NULL pointer), and then you're calling h->registerexplosion() on the NULL pointer.
Don't do that. Pass in a valid pointer instead, or allocate a new object (making sure you delete it properly later).
Related
It seems that, when I pass an class it is not passing a persistant (the same) instance of that class as I would expect. I'm assuming this has something to do with memory state but I would appreciate it if someone could explain exactly what is happening. The issue is easily demonstrated as follows :
Main.ino
#include "Debug.h"
#include "Box.h"
Debug debug;
Box box(debug);
void loop(){
debug.message("loop");
debug.line();
}
void setup(){
debug.init();
box.init();
debug.message("Setup Complete");
debug.line();
}
Debug.h
#ifndef DEBUG_H
#define DEBUG_H
class Debug {
private:
bool state;
public:
Debug();
void init();
void message(const char *str);
void message(int);
void line();
};
#endif
Debug.cpp
#include "Debug.h"
#include <Arduino.h>
Debug::Debug() : state(false) {}
void Debug::init() {
if (state == false){
Serial.begin(9600);
state = true;
}
}
void Debug::message(const char *messageChar) {
if (state){
const char *p;
p = messageChar;
while (*p) {
Serial.print(*p);
p++;
}
}
}
void Debug::message(int messageInt) {
if (state){
Serial.print(messageInt);
}
}
void Debug::line() {
if (state){
Serial.println();
}
}
Box.h
#ifndef BOX_H
#define BOX_H
#include "Debug.h"
class Box {
private:
Debug debug;
public:
Box(Debug &debug);
void init();
};
#endif
Box.cpp
#include "Box.h"
#include <Arduino.h>
Box::Box(Debug &debug):
debug(debug)
{}
void Box::init(){
// Switches
pinMode(28, INPUT_PULLUP);
debug.message("Box intialized");
debug.line();
}
So the above code outputs to serial:
Setup Complete
If I modify Box::init() to
void Box::init(){
// Switches
pinMode(28, INPUT_PULLUP);
debug.init();
debug.message("Box intialized");
debug.line();
}
I get what I want :
Box initialized
Setup Complete
If I get rid of Box constructor class and instead do
void Box::init(Debug &debug){
this->debug = debug;
// Switches
pinMode(28, INPUT_PULLUP);
debug.message("Box intialized");
debug.line();
}
Called via Main.ino like
void setup(){
debug.init();
box.init(debug);
debug.message("Setup Complete");
debug.line();
}
I get the desired response again. I don't understand why my first attempt doesn't work nor do I feel comfortable knowing what best practices are. I would appreciate any guidance.
You have two Debug values in your code. One global, one member of the Box class.
Those are two distinct values, since Box create or copy from a value to create its own, and there's the global one.
A solution would be to contain a reference or a pointer.
Here's the example with a reference:
class Box {
private:
Debug& debug;
// ^---- there
public:
Box(Debug &debug);
void init();
};
If you want Box to still be assignable, then use a pointer:
class Box {
private:
Debug* debug;
// ^---- now it's a star
public:
Box(Debug &debug);
void init();
};
Box::Box(Debug &debug):
debug(&debug)
{} // ^----- here, we take the address of the debug variable.
Since references are immutable, you loose some important feature of the language: assignment.
struct thing {
int& ref;
};
int main () {
int a, b;
thing t1{a}, t2{b};
t1 = t2; // ERROR!
}
The assignment would cause t1.ref to point to b after the assignment.
Pointer has a more difficult syntax and hard to guess semantics. However, they play very well with assignment since they give you more freedom:
struct thing {
int* ptr;
};
int main () {
int a, b;
thing t1{&a}, t2{&b};
t1 = t2; // Works, t1.ptr points to b
}
I was tasked to debug a code that was meant to draw a simple polygon out of 4 points using FLTK. The MyWindow class derive from Fl_Window. The Shape class is the parent class for ClosedPolyline. Both MyWindow and Shape hold a vector to draw all of the shapes.
The problem is that after compiling and run, win.show() opens an empty window without any drawing. I'm puzzled to understand this behavior.
Here is the code (I've omitted some of the parts that are not related to drawing ClosedPolyline):
#include <iostream>
#include <FL/Fl.H>
#include <FL/Fl_Draw.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Device.H>
#include <initializer_list>
#include <vector>
#include <functional>
//#include <cmath>
//#include <math.h>
struct Point {
int x,y;
Point(int xx, int yy) : x(xx), y(yy) { }
};
class Shape{
public:
Point point(int idx) const {
return (points[idx]);
}
unsigned int points_size() const {
return points.size();}
void draw() /*const*/{
draw_lines();
}
void add(Point p){ points.push_back(p); }
protected:
virtual void draw_lines() {}
private:
std::vector<Point> points;
};
class ClosedPolyline: public Shape {
public:
/*ClosedPolyline(std::initializer_list<Point> pp) {
if (pp.size() > 0) {
for (Point p: pp)
add(p);
}
}
*/
ClosedPolyline(Point a1, Point a2, Point a3, Point a4){
add(a1); add(a2); add(a3); add(a4);
}
protected:
void draw_lines() override{
for (unsigned int i=1; i<points_size(); ++i){
fl_line(point(i-1).x, point(i-1).y, point(i).x, point(i).y);
}
}
};
class MyWindow: public Fl_Window {
public:
MyWindow(int x, int y, int w, int h, const char* title = 0)
: Fl_Window(x, y, w, h, title) {}
void Attach(Shape s) {
shapes.push_back(&s);
}
//void draw_shapes(){draw();}
protected:
void draw() override{
for(Shape * s: shapes) {
s->draw();
//s.draw();
}
}
private:
std::vector<Shape*> shapes;
};
And here is the main() function:
int main() {
MyWindow win(100, 100, 600, 400, "C++ Test task");
ClosedPolyline p{Point{100, 100}, Point{100, 200}, Point{500, 100}, Point{500, 200}};
win.Attach(p);
win.end();
win.show();
return (Fl::run());
}
Lets take a look at your MyWindow::Attach function:
void Attach(Shape s) {
shapes.push_back(&s);
}
In the function, the argument s is passed by value. That means it's the same as a local variable inside the function. And as such it will go out of scope and be destructed once the function return.
Saving a pointer to that variable will lead to you saving a stray pointer, pointing to a non-existing object. Dereferencing that pointer will lead to undefined behavior, turning your whole program ill-formed and invalid.
One way to solve the problem is to make sure that the object don't go out of scope. This can be done by using smart pointers like e.g. std::unique_ptr. And to use it from the beginning already when you define the variable p in the main function.
Another way to solve your problem is to assume that the Shape passed to Attach will have a lifetime that outlives the Shape object, and you could therefore pass the Shape by reference:
void Attach(Shape& s) {
shapes.push_back(&s);
}
Now you no longer get a copy of the Shape object, and push a pointer to the original object (in your case the object p in the main function). Dereferencing the pointer will be valid as long as the original object is alive and in scope.
I try run that code in VS2015 and get a lot of error( of course fix attach window pass by reference ) But when I run to linux , it can draw, So I think you should move to linux.
I am trying to implement a Polynomial structure using a linked list of Terms (the linked list is implemented separately).
When I run my main program, I get a (Thread 1: EXC_BAD_ACCESS code=2) error on the line
coeff = x; in the definition my setCoeff function.
I tried commenting out that specific function call, but it gives me the same error for the setX() and setY() functions.
I think I have my files and functions set up properly, I cannot figure out why it is not letting me use these functions.
Please help !
In order, I have included: Polynomial.h, Polynomial.cpp, and main.cpp.
#ifndef __Polynomial__Polynomial__
#define __Polynomial__Polynomial__
#include <stdio.h>
class Term {
private:
int coeff;
int deg_x;
int deg_y;
public:
Term();
int getCoeff();
int getX();
int getY();
void setX(int);
void setY(int);
void setCoeff(int);
};
#endif /* defined(__Polynomial__Polynomial__) */
___________________________
#include "Polynomial.h"
Term::Term() {
coeff = NULL;
deg_x = NULL;
deg_y = NULL;
}
int Term::getCoeff(){
return coeff;
}
int Term::getX() {
return deg_x;
}
int Term::getY() {
return deg_y;
}
void Term::setX(int x){
deg_x = x;
}
void Term::setY(int x){
deg_y = x;
}
void Term::setCoeff(int x){
coeff = x;
}
__________________________
#include <iostream>
#include <fstream>
#include "Polynomial.h"
int main() {
Term* t1;
t1->setCoeff(4);
t1->setX(3);
t1->setY(6);
}
You never create an object. You have Term* t1, which is an uninitialized pointer to random memory, then you try to use it with t1->setCoeff(4) which is trying to use an object that was never created. That's definitely gonna go wrong.
Do this instead..
auto t1 = std::make_unique<Term>();
Or if you don't need it to be a pointer, you can create a simple stack variable and access it with '.' operator like this ...
Term t1;
t1.setCoeff(4);
t1.setX(3);
t1.setY(6);
Basically for some reason new object is wrong type. All source code is on github https://github.com/teuro/sfml-radar. If it's help please fork at will.
I have following class:
#ifndef _VIEW_HPP
#define _VIEW_HPP
#include <iostream>
#include "sfml_drawsurface.hpp"
class View {
protected:
View(Drawsurface& d) : drawer(d) {
std::clog << "View::View()" << std::endl;
}
Drawsurface& drawer;
virtual void draw() = 0;
};
#endif
That is base class for all different kind of views. Now I have derived sub-class
#ifndef _GAME_VIEW_HPP
#define _GAME_VIEW_HPP
#include <vector>
#include <iostream>
#include <typeinfo>
#include "view.hpp"
#include "../models/game.hpp"
class Gameview : public View {
public:
Gameview(Drawsurface& d);
~Gameview();
void draw();
private:
Drawsurface& drawer;
};
#endif // _GAME_VIEW_HPP
Then abstract class Drawsurface
/**
* drawsurface base for all graphics pure abstract
* provide only interface quite high-level
* 2014/06/02
* Juha Teurokoski
**/
#ifndef _DRAWSURFACE_HPP
#define _DRAWSURFACE_HPP
#include <string>
#include "../models/point.hpp"
class Drawsurface {
public:
bool font_loaded;
virtual void rectangleColor(Point& a, Point& b, unsigned int color) = 0;
virtual void lineColor(Point& a, Point& b, unsigned int color) = 0;
virtual void circleColor(Point& a, unsigned int rad, unsigned int color) = 0;
virtual void trigonColor(Point& a, Point& b, Point& c, unsigned int color) = 0;
virtual void trigonColor(Point& a, unsigned int size, unsigned int color) = 0;
virtual void load_font(std::string font) = 0;
virtual void draw_picture(std::string tiedosto, Point& a, bool center = false) = 0;
virtual void draw_text(std::string text, Point& a, unsigned int color = 0) = 0;
virtual int get_fontsize() = 0;
virtual void flip() = 0;
virtual void clear_screen() = 0;
virtual ~Drawsurface() { }
};
#endif
Now if I create new instance of sfml_drawsurface which is sub-class of Drawsurface. For some reason new object is Drawsuface istead of sfml_drawsurface. Below is sfml_drawsurface class.
#ifndef SFML_DRAWSURFACE_HPP
#define SFML_DRAWSURFACE_HPP
/**
* sfml-drawsurface provides basic drawing, pictures and text
* require drawsurface
* 2014/06/02
* Juha Teurokoski
**/
#include "drawsurface.hpp"
#include <vector>
#include <stdexcept>
#include <iostream>
#include <SFML/Graphics.hpp>
class sfml_drawsurface : public Drawsurface {
public:
sfml_drawsurface(sf::RenderWindow& window);
~sfml_drawsurface();
void rectangleColor(Point& a, Point& b, unsigned int color);
void circleColor(Point& a, unsigned int rad, unsigned int color);
void lineColor(Point& a, Point& b, unsigned int color);
void trigonColor(Point& a, Point& b, Point& c, unsigned int color);
void trigonColor(Point& a, unsigned int _size, unsigned int color);
void draw_picture(std::string tiedosto, Point& a, bool center = false);
void draw_text(std::string text, Point& a, unsigned int color);
void load_font(std::string font);
void clear_screen();
int get_fontsize();
void flip();
protected:
private:
sf::RenderWindow& window;
sf::Font font;
sf::Color active;
sf::Color normal;
};
#endif // SFML_DRAWSURFACE_HPP
I create new object like this:
sfml_drawsurface drawer(window);
this->gameview = new Gameview(drawer);
std::clog << typeid(drawer).name() << std::endl;
And everything seems to be right, because std::clog outout is '16sfml_drawsurface'.
Next place is draw-method then happens something really weird.
Same print is now '11Drawsurface'.
Looks like Mike had the right idea. From your Program.cpp file you have in your constructor:
Program::Program() {
Game game;
...
this->gamecontroller = new Gamecontroller(game); //Probably also bad
sfml_drawsurface drawer(window);
this->gameview = new Gameview(drawer);
}
The problem is that drawer ceases to exist once the constructor is finished leaving you with a dangling reference and undefined behaviour. Looks like you may have the same problem with the game variable.
Solution is to not have them as local variables but as either class members (preferred) or dynamically allocated (it depends how long you need to have them around).
I have 2 projects decoder and dec in my visual studio. One has C code and other has C++ code using stl respectively.How do I instantiate the c++ classes in my c code inside decode project?
for e.g.
//instantiating object
reprVectorsTree *r1 = new reprVectorsTree(reprVectors1,8);
//using one of its function
r1->decode(code);
What do I need to do for this?
How do I access files from another project?
How do I make use of existing c++ code in C files?
--------edit----------
I have a class like this
class Node//possible point in our input space
{
public:
std::vector<float> valuesInDim;//values in dimensions
std::vector<bool> code;
Node(std::vector<float>value);
Node::Node(float x, float y);
Node::Node(std::vector<float> value,std::vector<bool> binary);
};
How do I use the above class in c++?
If C only allows structs how do I map it to a struct?
Give the C++ module a C interface:
magic.hpp:
struct Magic
{
Magic(char const *, int);
double work(int, int);
};
magic.cpp: (Implement Magic.)
magic_interface.h:
struct Magic;
#ifdef __cplusplus
extern "C" {
#endif
typedef Magic * MHandle;
MHandle create_magic(char const *, int);
void free_magic(MHandle);
double work_magic(MHandle, int, int);
#ifdef __cplusplus
}
#endif
magic_interface.cpp:
#include "magic_interface.h"
#include "magic.hpp"
extern "C"
{
MHandle create_magic(char const * s, int n) { return new Magic(s, n); }
void free_magic(MHandle p) { delete p; }
double work_magic(MHandle p, int a, int b) { return p->work(a, b); }
}
Now a C program can #include "magic_interface.h" and use the code:
MHandle h = create_magic("Hello", 5);
double d = work_magic(h, 17, 29);
free_magic(h);
(You might even want to define MHandle as void * and add casts everywhere so as to avoid declaring struct Magic in the C header at all.)
In simple terms, you just do these:
Write an interface function to convert all the class functions (constructor, destructor, member functions) as pure functions, and encapsulate them as extern "C"{ }
Convert the pointer to the class as pointer to void, and carefully use type-cast wherever you define the "pure functions"
Call the pure functions in the C-code.
For example here is my simple Rectangle class:
/*** Rectangle.h ***/
class Rectangle{
private:
double length;
double breadth;
public:
Rectangle(double iLength, double iBreadth);
~Rectangle();
double getLength();
double getBreadth();
};
/*** Rectangle.cpp ***/
#include "Rectangle.h"
#include <iostream>
extern "C" {
Rectangle::Rectangle(double l, double b) {
this->length = l;
this->breadth = b;
}
Rectangle::~Rectangle() {
std::cout << "Deleting object of this class Rectangle" << std::endl;
}
double Rectangle::getLength() {
return this->length;
}
double Rectangle::getBreadth() {
return this->breadth;
}
}
Now here is my interface to convert the class functions to pure functions. Notice how the pointer to the class is handled!
/*** RectangleInterface.h ***/
#ifdef __cplusplus
extern "C" {
#endif
typedef void * RHandle;
RHandle create_Rectangle(double l, double b);
void free_Rectangle(RHandle);
double getLength(RHandle);
double getBreadth(RHandle);
#ifdef __cplusplus
}
#endif
/*** RectangleInterface.cpp ***/
#include "RectangleInterface.h"
#include "Rectangle.h"
extern "C"
{
RHandle create_Rectangle(double l, double b){
return (Rectangle*) new Rectangle(l, b);
};
void free_Rectangle(RHandle p){
delete (Rectangle*) p;
}
double getLength(RHandle p){
return ((Rectangle*) p)->getLength();
}
double getBreadth(RHandle p){
return ((Rectangle*)p)->getBreadth();
}
}
Now I can use these interface functions in my ".c" file as shown below. I just have to include the RectangleInterface.h function here, and the rest is taken care by its functions.
/*** Main function call ***/
#include <stdio.h>
#include "RectangleInterface.h"
int main()
{
printf("Hello World!!\n");
RHandle myRec = create_Rectangle(4, 3);
printf("The length of the rectangle is %f\n", getLength(myRec));
printf("The area of the rectangle is %f\n", (getLength(myRec)*getBreadth(myRec)));
free_Rectangle(myRec);
return 0;
}
Make wrapper for instantiating C++ objects using C++ exported functions.And then call these functions from C code to generate objects.
Since one is function oriented and other is object oriented, you can use a few ideas in your wrapper:-
In order to copy class member, pass an equivalent prespecified struct from C code to corresponding C++ function in order to fetch the data.
Try using function pointers, as it will cut the cost, but be careful they can be exploited as well.
A few other ways.
you would need to write a wrapper in C.
something like this:
in class.h:
struct A{
void f();
}
in class.cpp:
void A::f(){
}
the wrapper.cpp:
#include "wrapper.h"
void fWrapper(struct A *a){a->f();};
struct A *createA(){
A *tmp=new A();
return tmp;
}
void deleteA(struct A *a){
delete a;
}
the wrapper.h for C:
struct A;
void fWrapper(struct A *a);
A *createA();
the C program:
#include "wrapper.h"
int main(){
A *a;
a=createA();
fWrapper(a);
deleteA(a);
}