Accessing member variables gives SIGSEGV - c++

Im trying to create a GUI using the library Irrlicht in C++, however whilst wring my Gui Handler, I get SIGSEGV errors when trying to access any data outside the constructor.
My header looks like this:
#pragma once
#include <irrlicht.h>
#include "Structs.h"
#include <vector>
#include <string>
class GuiHandler
{
public:
GuiHandler(Structs::SAppContext *contIN);
~GuiHandler();
bool GuiEvent(const irr::SEvent& eventType);
struct RGBPicker
{
IGUIButton* sample;
IGUIStaticText* RGB[3];
IGUIEditBox* RGBValues[3];
int Colour[3];
};
RGBPicker bottomColour;
RGBPicker topColour;
int i;
}
The values are assigned to the 2 RGBPicker variables in the constructor in the cpp file:
GuiHandler::GuiHandler(Structs::SAppContext *contIN)
{
context = contIN;
int xpos = 185;
int ypos= 110;
//bottomColour.pickerTexture->fill(s)
bottomColour.sample = context->env->addButton(rect<s32>(128+xpos, 16+ypos, 198+xpos, 86+ypos), 0, 111, L"");
bottomColour.sample->setEnabled(false); //static box
bottomColour.RGBValues[0] = context->env->addEditBox(L"", rect<s32>(64+xpos, 64+ypos, 120+xpos, 84+ypos), true, 0, 113);
bottomColour.RGBValues[1] = context->env->addEditBox(L"", rect<s32>(64+xpos, 40+ypos, 120+xpos, 60+ypos), true, 0, 113);
bottomColour.RGBValues[2] = context->env->addEditBox(L"", rect<s32>(64+xpos, 16+ypos, 120+xpos, 36+ypos), true, 0, 113);
for(int i = 0; i < 3; i++)
{
bottomColour.RGBValues[i]->setMax(3);
bottomColour.RGBValues[i]->setText(L"0");
}
bottomColour.RGBValues[0]->setToolTipText(L"B1");
bottomColour.RGBValues[1]->setToolTipText(L"G1");
bottomColour.RGBValues[2]->setToolTipText(L"R1");
bottomColour.RGB[0] = context->env->addStaticText(L"B:", rect<s32>(48+xpos, 64+ypos, 66+xpos, 84+ypos), false, false, 0, -1,114);
bottomColour.RGB[1] = context->env->addStaticText(L"G:", rect<s32>(48+xpos, 40+ypos, 66+xpos, 60+ypos), false, false, 0, -1,114);
bottomColour.RGB[2] = context->env->addStaticText(L"R:", rect<s32>(48+xpos, 16+ypos, 66+xpos, 36+ypos), false, false, 0, -1,114);
std::cout<<i<<std::endl;
i=2;
std::cout<<i<<std::endl;
}
Whilst everything works within the header- accesing all the topColour, bottomColour and context statements, when in any other method within the class, they result in a SIGSEGV. Even printing out i with cout.
I know i must be doing very simple incorrectly however I can't work it out.
Thanks.

Related

How to properly use WriteConsoleInput function for KEY_EVENT?

To terminate a blocking Input from another thread, I tried to simulate a input event or more precisely a kayboard input using WriteConsoleInput function.
#include<Windows.h>
#include<conio.h>
#include<thread>
void KillBlockingIO() {
DWORD entityWritten;
INPUT_RECORD inputs;
inputs.EventType = KEY_EVENT;
inputs.Event.KeyEvent.bKeyDown = true;
inputs.Event.KeyEvent.uChar.AsciiChar = VK_RETURN;
inputs.Event.KeyEvent.wRepeatCount = 0;
inputs.Event.KeyEvent.dwControlKeyState = 0;
inputs.Event.KeyEvent.wVirtualKeyCode = 0;
inputs.Event.KeyEvent.wVirtualScanCode = 0;
// inputs.Event = { true, 0, 0, 0, VK_RETURN, 0 }; // same as above
Sleep(2000);
WriteConsoleInputA(GetStdHandle(STD_INPUT_HANDLE), &inputs, 1, &entityWritten);
}
int main()
{
std::thread t(KillBlockingIO);
char c = _getch();
printf("character recieved without typing: %c\n", c);
t.join();
}
It is working but I'm not sure, I've used WriteConsoleInput function property because members like wVirtualKeyCode, wVirtualScanCode and dwControlKeyState is set zero. No matter what value I pass, It is always going to have same result. It is also not very well Documented. I tried finding code examples but there is no such example.
what is purpose of these parameters and How to use WriteConsoleInput function properly?

How to return float32 array from c++ in node-addon-api?

I am trying to run c++ in node.js using node-addon-api.
I've read one well-written elaborate article from medium.
But I want to pass to one of my functions a float, and a float array to another function.
I want to return a float array from both of them.
The example of a function (greeting.cpp)
#include <iostream>
#include <string>
#include <cmath>
#include "greeting.h"
float* helloUser( float name ) {
float* result = new float[3];
result[0] = 1;
result[1] = 2;
result[2] = name;
return result;
}
And the code of index.cpp with a native implementation of the module:
#include <napi.h>
#include <string>
#include "greeting.h"
Napi::Float32Array greetHello(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
float user = (float) info[0].ToNumber();
float* result = helloUser( user );
return Napi::Float32Array::New(env, result);
}
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(
Napi::String::New(env, "greetHello"), // property name => "greetHello"
Napi::Function::New(env, greetHello) // property value => `greetHello` function
);
return exports;
}
NODE_API_MODULE(greet, Init)
The thing is, Napi::Float32Array doesn't work, I tried Napi::TypedArrayOf<float>, it doesn't work either. I am not that much into writing modules.
I just want my pure c++ code running in node to send its result to the frontend.
I tried accepting and returning floats with Napi::Number and it works fine.
But I have no clue how to get it start working with arrays.
Any help is appreciated.
I ran into a similar issue and the Napi instance methods expect either a:
void MethodName(const Napi::CallbackInfo& info);
or
Napi::Value MethodName(const Napi::CallbackInfo& info);
Even though Napi::TypedArray inherits from Napi::Object which inherits from Napi::Value, it turns out you have to explicitly return a Napi::Value as follows:
Napi::Value greetHello(Napi::CallbackInfo const& info)
{
Napi::Float32Array arr = Napi::Float32Array::New(info.Env(), 16);
arr[0] = 1;
arr[15] = 16;
return arr;
}
Which will get you a Float32Array:
{
greetHello: [Function (anonymous)]
}
Float32Array(16) [
1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 16
]

C++ object of abstract class type "mazeGenerator" is not allowed: pure virtual function "olcGameEngine::OnUserUpdate" has no overrider

So since im trying to learn c++ i have been followin onelonecoders tutorial, however i am stuck. The class that i made "mazeGenerator" will not be instantiated. other questions like mine have as solution using const on the onUserUpdate function however, this has not worked, I've had other problems that i was able to fix but i cant find a solution for this one.
Thank you very much in advance!
the solution is probably under my nose, but i just cant find it
Heres the code i have written so far:
// mazeGenerater.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#pragma once
#include <iostream>
#include <stack>
using namespace std;
#include "olcConsoleEngine.h"
class mazeGenerator : public olcConsoleGameEngine {
public:
mazeGenerator(){
m_sAppName = L"MAZE";
}
private:
int m_nMazeWidth;
int m_nMazeHeight;
int *m_maze;
enum{
CELL_PATH_N = 0x01,
CELL_PATH_E = 0x02,
CELL_PATH_S = 0x04,
CELL_PATH_W = 0x08,
CELL_VISITED = 0x10,
};
int m_nVisitedCells;
stack<pair<int , int>> m_stack; // (x, y) coordinate pairs
protected:
virtual bool OnUserCreate() {
//initialize alogrithm
m_nMazeWidth = 40;
m_nMazeHeight = 25;
//allocate maze memory
m_maze = new int[m_nMazeWidth * m_nMazeHeight];
memset(m_maze, 0x00, m_nMazeWidth * m_nMazeHeight);
//push cells to stack
m_stack.push(make_pair(0, 0));
m_maze[0] = CELL_VISITED;
m_nVisitedCells = 1;
return true;
}
virtual bool onUserUpdate(float fElppasedTime) {
// draw stuff
Fill(0, 0, ScreenWidth(), ScreenHeight(), L' ');
for (int x = 0; x < m_nMazeWidth; x++) {
for (int y = 0; y < m_nMazeHeight; y++) {
if (m_maze[y * m_nMazeWidth + x] & CELL_VISITED) {
Draw(x, y, PIXEL_SOLID, FG_WHITE);
}
else {
Draw(x, y, PIXEL_SOLID, FG_BLUE);
}
}
}
return true;
}
};
int main()
{
//create maze and run
mazeGenerator game;
game.ConstructConsole(160, 100, 8, 8);
game.Start();
return 0;
}
// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
// Debug program: F5 or Debug > Start Debugging menu
// Tips for Getting Started:
// 1. Use the Solution Explorer window to add/manage files
// 2. Use the Team Explorer window to connect to source control
// 3. Use the Output window to see build output and other messages
// 4. Use the Error List window to view errors
// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file
Here is lonecoders engine
https://github.com/OneLoneCoder/videos/blob/master/olcConsoleGameEngine.h
i would post the code of the engine itself but I'd end up with more than 30000 characters, sorry!
I think that the problem is that the function you wrote in the derived class, onUserUpdate, should be OnUserUpdate - with a capital O.
In addition, add the override keyword before the function implementation. Change
virtual bool onUserUpdate(float fElppasedTime) {
^^^^^^^
into this
bool onUserUpdate(float fElppasedTime) override {
^^^^^^^^
for all overridden functions - and you will see the errors.

weird access violation error

I'm getting a (to me) weird run-time access violation error.
I have a class, GUI, that contains a raw pointer to an instance of another class, Crosshair. However, when I try to access that pointer, I get a run-time error! I'm talking about accessing the pointer, I don't even have to dereference it to get the error.
Here's the error:
Unhandled exception at 0x00d4c486 in GPEngine.exe: 0xC0000005: Access violation reading location 0x00000004.
The error returns to this line: int a = (int)m_pCrosshair;
Which is in the GUI::Draw() method, provided below.
EDIT:
I found the problem. It occurred in code I was hiding from you guys, while trying to hide as much irrelevant code as possible... The problem was this:
bool PsychoBots_Game::InitGame()
{
//more code...
return true;
//////GUI
GUIOnIntialisationInfo GUIdesc;
GUIdesc.pContentManager = m_pContentManager;
GUIdesc.pDevice = m_pLevel->GetDevice();
m_pGUI = new GUI(GUIdesc);
}
Pure stupidity, in other words... Sorry for this! I did not write the first part of that method so I wasn't aware of the return values since I never use this when initialising my own stuff...
Old:
Code:
Crosshair.h
#pragma once
#include "D3DUtil.h"
class ContentManager;
class RenderContext;
class Crosshair
{
public:
Crosshair(ID3D10Device* pDevice, ContentManager *pContentManager);
virtual ~Crosshair();
void Draw(ID3D10Device* pDevice, int clientWidth, int clientHeight);
private:
ID3D10InputLayout* m_pVertexLayout;
ID3D10Buffer* m_pVertexBuffer;
ID3D10Effect* m_pDefaultEffect;
ID3D10EffectTechnique* m_pDefaultTechnique;
ID3D10EffectMatrixVariable* m_pWVPVariable;
ID3D10EffectShaderResourceVariable* m_pDiffuseMapVariabele;
ID3D10ShaderResourceView * m_pTextureRV;
private:
//disabled
Crosshair(const Crosshair& b);
Crosshair& operator= (const Crosshair& b);
};
Crosshair.cpp
#include "stdafx.h"
#include "Crosshair.h"
#include "ContentManager.h"
#include "RenderContext.h"
#include "vertex.h"
Crosshair::Crosshair(ID3D10Device* pDevice, ContentManager *pContentManager)
:m_pVertexLayout(nullptr)
,m_pVertexBuffer(nullptr)
,m_pDefaultEffect(nullptr)
,m_pDefaultTechnique(nullptr)
,m_pWVPVariable(nullptr)
,m_pDiffuseMapVariabele(nullptr)
,m_pTextureRV(nullptr)
{
//////Load Texture
m_pTextureRV = pContentManager->GetTexture(pDevice, _T("GUI/Crosshair.png"));
//////Load Effect & Technique
m_pDefaultEffect = pContentManager->GetEffect(pDevice, _T("Effect/Texture2D.fx"));
//get technique
m_pDefaultTechnique = m_pDefaultEffect->GetTechniqueByIndex(0);
if(!m_pDefaultTechnique->IsValid())
{
MessageBox(0,_T("Technique not valid"),_T("ERROR"),0);
exit(-1);
}
//////Get Effect Variables
m_pDiffuseMapVariabele = m_pDefaultEffect->GetVariableBySemantic("DiffuseMap")->AsShaderResource();
if(!m_pDiffuseMapVariabele->IsValid()) {
MessageBox(0,_T("Getting EffectVariable m_pDiffuseMapVariabele Failed"),_T("ERROR"),0);
exit(-1);
}
m_pWVPVariable = m_pDefaultEffect->GetVariableBySemantic("WVP")->AsMatrix();
if(!m_pWVPVariable->IsValid()) {
MessageBox(0,_T("Getting EffectVariable m_pWVPVariable Failed"),_T("ERROR"),0);
exit(-1);
}
//////Define InputLayout
D3D10_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }
};
UINT numElements = sizeof(layout)/sizeof(layout[0]);
// Create the input layout
D3D10_PASS_DESC PassDesc;
// Get the pass decriptor from the effect technique
m_pDefaultTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
HR(pDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &m_pVertexLayout ));
//////Build Vertexbuffer
VertexPosTex v[4];
v[0].pos = D3DXVECTOR3(-0.5f, -0.5f, 0.0f); v[0].tex.x = 0.0f; v[0].tex.y = 1.0f;
v[1].pos = D3DXVECTOR3(-0.5f, 0.5f, 0.0f); v[1].tex.x = 0.0f; v[1].tex.y = 0.0f;
v[2].pos = D3DXVECTOR3( 0.5f, -0.5f, 0.0f); v[2].tex.x = 1.0f; v[2].tex.y = 1.0f;
v[3].pos = D3DXVECTOR3( 0.5f, 0.5f, 0.0f); v[3].tex.x = 1.0f; v[3].tex.y = 0.0f;
//fill a buffer description to copy the vertexdata into graphics memory
D3D10_BUFFER_DESC bd = {};
bd.Usage = D3D10_USAGE_DEFAULT;
bd.ByteWidth = sizeof( VertexPosTex ) * sizeof(v);
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA initData;
initData.pSysMem = v;
//create a ID3D10Buffer in graphics memory containing the vertex info
HR(pDevice->CreateBuffer( &bd, &initData, &m_pVertexBuffer ));
}
Crosshair::~Crosshair()
{
m_pVertexLayout->Release();
m_pVertexBuffer->Release();
}
void Crosshair::Draw(ID3D10Device* pDevice, int clientWidth, int clientHeight)
{
//////Set the input layout
pDevice->IASetInputLayout( m_pVertexLayout );
//more code...
}
GUI.h
#pragma once
#include "D3DUtil.h"
#include "GUIOnInitialisationInfo.h"
#include "GUIPerFrameInfo.h"
#include "GUIPerTickInfo.h"
#include "Crosshair.h"
class GUI
{
public:
virtual ~GUI();
GUI(const GUIOnIntialisationInfo& info);
void Tick(const GUIPerTickInfo& info);
void Draw(const GUIPerFrameInfo& info);
private:
Crosshair* m_pCrosshair;
};
GUI.cpp
#include "stdafx.h"
#include "GUI.h"
GUI::GUI(const GUIOnIntialisationInfo& info)
:m_pCrosshair(new Crosshair(info.pDevice, info.pContentManager))
{
}
GUI::~GUI()
{
delete m_pCrosshair;
}
void GUI::Tick(const GUIPerTickInfo& info)
{
}
void GUI::Draw(const GUIPerFrameInfo& info)
{
int a = (int)m_pCrosshair;
m_pCrosshair->Draw(info.pDevice, info.clientWidth, info.clientHeight);
}
The error returns to this line: int a = (int)m_pCrosshair;
When I delete this line: it will break at m_pCrosshair->Draw(info.pDevice, info.clientWidth,info.clientHeight);
With error: Unhandled exception at 0x001fc49a in GPEngine.exe: 0xC0000005: Access violation reading location 0x00000004
Here is how an instance of GUI is intantiated in my application:
class PsychoBots_Game : public D3DApp
{
//more code...
private:
GUI* m_pGUI;
//more code...
};
(please don't ask me why I have an InitGame() method, we have to do this to make our teachers happy [lol])
bool PsychoBots_Game::InitGame()
{
//////GUI
GUIOnIntialisationInfo GUIdesc;
GUIdesc.pContentManager = m_pContentManager;
GUIdesc.pDevice = m_pLevel->GetDevice();
m_pGUI = new GUI(GUIdesc);
}
And finally, WinMain:
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
TCHAR* cmdLine, int showCmd)
{
PsychoBots_Game *pGameApp= new PsychoBots_Game(hInstance);
if(pGameApp->InitApp())pGameApp->Run();
delete pGameApp;
}
Can anyone tell me what is causing the problem? If by any chance you still need more code, just ask in a comment :)
Thanks
There is a dereference in your class, but one you don't see: m_pCrosshair is a member, so any access will go through the this pointer, which seems to be 0 according to the error. I can't find the invocation site of GUI::Draw, but the instance pointer there is 0 or uninitialized.
Your bool PsychoBots_Game::InitGame() does not return value.
Are you sure that Draw method is being called on m_pGUI?
Are your sure PsychoBots_Game::InitGame() is being called ? From the code your provided only pGameApp->InitApp() is called. m_pGUI is initialized in InitGame.
The class class GUI does not obey the rule of three (while containing a RAW pointer).
Thus you probably have made a copy of the object and the original object got deleted thus leaving you with an object with an invalid pointer.
There is an easy way to check if this is the problem: Make the copy constructor and assignment operator if GUI private if you get a compile time error then this is your problem.
As a side note your code contains way to many RAW pointers.
You should take a look what really needs to be pointers and what can be normal objects. In places where you must have pointers then look at using smart pointers.

How to use Fl::awake in the FLTK Library

I would like to use the Fl::awake(callback) function to call functions from my main loop in an FLTK program. I am calling Fl::awake from a child thread, it returns 1 (success), but my function never gets called. I am calling Fl::wait() in a loop in the main thread. Is there any way i can troubleshoot this?
Code below is an example of a relatively simple FLTK 1.3 application which uses Fl::awake(callback) . The code is from the FLTK's test directory. Just fetch the source, and you'll find numerous examples. You did not give us your code, but I assume you did not call Fl::lock(), and later Fl::unlock() in your thread. It is essential because you should not access widgets outside that section...
include
#if HAVE_PTHREAD || defined(WIN32)
# include <FL/Fl.H>
# include <FL/Fl_Double_Window.H>
# include <FL/Fl_Browser.H>
# include <FL/Fl_Value_Output.H>
# include <FL/fl_ask.H>
# include "threads.h"
# include <stdio.h>
# include <math.h>
Fl_Thread prime_thread;
Fl_Browser *browser1, *browser2;
Fl_Value_Output *value1, *value2;
int start2 = 3;
void magic_number_cb(void *p)
{
Fl_Value_Output *w = (Fl_Value_Output*)p;
w->labelcolor(FL_RED);
w->redraw_label();
}
void* prime_func(void* p)
{
Fl_Browser* browser = (Fl_Browser*) p;
Fl_Value_Output *value;
int n;
int step;
char proud = 0;
if (browser == browser2) {
n = start2;
start2 += 2;
step = 12;
value = value2;
} else {
n = 3;
step = 2;
value = value1;
}
// very simple prime number calculator !
//
// The return at the end of this function can never be reached and thus
// will generate a warning with some compilers, however we need to have
// a return statement or other compilers will complain there is no return
// statement. To avoid warnings on all compilers, we fool the smart ones
// into beleiving that there is a chance that we reach the end by testing
// n>=0, knowing that logically, n will never be negative in this context.
if (n>=0) for (;;) {
int pp;
int hn = (int)sqrt((double)n);
for (pp=3; pp<=hn; pp+=2) if ( n%pp == 0 ) break;
if (pp >= hn) {
char s[128];
sprintf(s, "%d", n);
// Obtain a lock before we access the browser widget...
Fl::lock();
browser->add(s);
browser->bottomline(browser->size());
if (n > value->value()) value->value(n);
n += step;
// Release the lock...
Fl::unlock();
// Send a message to the main thread, at which point it will
// process any pending redraws for our browser widget. The
// message we pass here isn't used for anything, so we could also
// just pass NULL.
Fl::awake(p);
if (n>10000 && !proud) {
proud = 1;
Fl::awake(magic_number_cb, value);
}
} else {
// This should not be necessary since "n" and "step" are local variables,
// however it appears that at least MacOS X has some threading issues
// that cause semi-random corruption of the (stack) variables.
Fl::lock();
n += step;
Fl::unlock();
}
}
return 0L;
}
int main(int argc, char **argv)
{
Fl_Double_Window* w = new Fl_Double_Window(200, 200, "Single Thread");
browser1 = new Fl_Browser(0, 0, 200, 175);
w->resizable(browser1);
value1 = new Fl_Value_Output(100, 175, 200, 25, "Max Prime:");
w->end();
w->show(argc, argv);
w = new Fl_Double_Window(200, 200, "Six Threads");
browser2 = new Fl_Browser(0, 0, 200, 175);
w->resizable(browser2);
value2 = new Fl_Value_Output(100, 175, 200, 25, "Max Prime:");
w->end();
w->show();
browser1->add("Prime numbers:");
browser2->add("Prime numbers:");
// Enable multi-thread support by locking from the main
// thread. Fl::wait() and Fl::run() call Fl::unlock() and
// Fl::lock() as needed to release control to the child threads
// when it is safe to do so...
Fl::lock();
// Start threads...
// One thread displaying in one browser
fl_create_thread(prime_thread, prime_func, browser1);
// Several threads displaying in another browser
fl_create_thread(prime_thread, prime_func, browser2);
fl_create_thread(prime_thread, prime_func, browser2);
fl_create_thread(prime_thread, prime_func, browser2);
fl_create_thread(prime_thread, prime_func, browser2);
fl_create_thread(prime_thread, prime_func, browser2);
fl_create_thread(prime_thread, prime_func, browser2);
Fl::run();
return 0;
}
#else
# include <FL/fl_ask.H>
int main() {
fl_alert("Sorry, threading not supported on this platform!");
}
#endif // HAVE_PTHREAD || WIN32