I have a pretty weird error while trying to implement a board game in QT. This is my second time, having the same issue, and now i think it's time to ask here.
I'm still at the game's logic part, which have a class named Field, and a class named Board. The Board class has a QVector < Field* > fields attribute, which is a vector of Field pointers. And here is the problem. I have a function which supposed to upload this vector with new Fields. Here is my source, it's pretty straight forward:
void Board::addFields()
{
for(int i = 0; i<size; i++) //the board's size is size x size
{
for(int j = 0; j<size; j++)
{
Field * f = new Field();
fields.push_back(f);
//qDebug()<<i*size+j<<" "<<f;
}
}
//qDebug()<<fields.size();
}
And after i got a ton of weird errors, i decided to write to the console the actual number of elements, the reference of the actual element, and after the two loop the size of the vector.
The result was pretty strange, i got no errors, but somtimes it added all my elements, sometimes it stopped at a random number of elements, and the size of the vector doesnt even got printed out like this:
result 1 (normal):
0 0xa173a8
...
24 0x701c18
25
result 2 (??? every time with a different number of elements):
0 0xa173a8
...
12 0xa17548
//and no vector size, i assume the function got a return; because of something
I tried it with both QVector, and std::vector, it's the same. Please if someone got any idea, what the problem could be, tell me!
Thanks, and sorry for my english!
EDIT
All my code is here:
field.h: http://paste2.org/p/1937231
field.cpp: http://paste2.org/p/1937232
player.h: http://paste2.org/p/1937238
player.cpp: http://paste2.org/p/1937239
board.h: http://paste2.org/p/1937234
board.cpp: http://paste2.org/p/1937235
main.cpp: http://paste2.org/p/1937243
Thanks Everyone for the help, i found the solution.
Since i was making the logic part of a window application, i started a QT gui project. It generated for me a main() function with this:
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
I didn't know what this is, but because i didn't need any windows for now, i removed the code, and replaced it with my code, and a simple return 0; at the end. This must have caused the problem, because when i added the QApplication to the code again:
QApplication a(argc, argv);
Board b(10);
return a.exec();
It worked like a charm...
I don't know what to do in this case, if i could, i would give the point to all of you, who tried to help. But anyways, thank you very much for the help! :)
When you type new Field(); you make a dynamic memory allocation. The returned pointer actually is quite random, and you should not rely on it to be sequential. But normally that is no problem.
And after i got a ton of weird errors, i decided to write to the console the actual number of elements, the reference of the actual element, and after the two loop the size of the vector.
What errors are you experiencing exactly?
Is size a member? for my experience if things happen randomly it's 98% caused by members not initialized..
I don't know details of object initialization in C++, but
Board::Board(int size):size(size)
{
playerOne = new Player("Player One");
playerTwo = new Player("Player Two");
newGame(this->size);
}
may be the cause of the trouble. indeed, newGame use fields which is not explicitely initialized. So try using
Board::Board(int size):size(size), fields(size*size) //or just fields()
{
...
}
And tell us what happens.
Related
lets say I have a class "Second_Counter".
Its fields are:
int uptime{0};
std::thread second_counter_thread;
And it has the following methods:
Second_Counter::Second_Counter(){
this->second_counter_thread = get_second_counter_thread(&(this->uptime));
}
std::thread Second_Counter::get_second_counter_thread(int* i){
return std::thread (second_counter_loop, i);
}
void Second_Counter::second_counter_loop(int* i){
while(true){
std::this_thread::sleep_for(std::chrono::seconds(1));
(*i)++;
}
}
int Second_Counter::get_uptime(){
return this->uptime;
}
When I create one instance of Second_Counter, everything works as expected (get_uptime() always returns a correctly incremented integer).
However, as soon as I create another instance of Second_Counter, the first Second_Counter's uptime field doesn't seem to be incremented anymore (get_uptime() always returns the value that the first Second_Counter's uptime filed had when the second one started).
Strangely, when I print out i inside both second_counter_loops, it seems like both loops are still running (the i's of both loops are still getting incremented)
I solved my problem, and it actually hat little to do with what I thought.
I was creating the objects in question inside a loop that looked something like this:
while(something){
... obtain info_x for constructor...
bool add {true};
for(int i {0}; i < second_counter_list->size(); i++){
if(second_counter_list->at(i)->get_info_x() == info_x) add = false;
}
if (add) {
second_counter_list->emplace_back(info_x)); <-- I think this was the problem
}
}
(info_x is missing in my example above)
I still don't really know what has caused the problems in question, However trial and error let me to the conclusion that this line was causing unexpected behaviour. Maybe initializing a std::thread field through an emplace_back call doesn't work for some reason?
Now, instead of using a std::vector and the loop above, I switched to using a std::vector < std::unique_ptr < Second_Counter > > and allocating on the heap like this:
if (add) {
second_counter_list->push_back(std::make_unique<Second_Counter>(info_x));
}
And everything works as expected.
Hello i got a problem with getting the size of a ROS::Message which is vector
I have got the NaviManeuverSequence.msg:
Header header
uint8 carid
NaviManeuver[] maneuvers
and in maneuvers I sometimes have 3 vectors but sometimes also more. So I wanted to get the size of this vector by
NaviManeuverSequence.maneuvers.size();
but with this code I am just getting a 0 even though i can see in the debugger of Qt Creator that there are 3 Vectors in it.
Screenshot of debugger:
screenshot of debugger
Thanks for your help mates
Edit:
I have forgotten to say that NaviManeuver[] contains a maneuvers message which contains uints, floats and more Vectors
Edit2 Working Example of my Subscriber:
Class Maneuver {
Maneuver() {
naviManeuverSubscriber = navi_node.subscribe("/mad/maneuver_sequence", 100, &ManeuverManagement::naviCallback, this);
}
void step() {
uint32_t variable = naviManeuverSequence.maneuvers.size();
}
}
Firstly I initialize value in constructor in Ford Bellman claas
FordBellman::FordBellman() {
this->vertexCount=0;
this->vertexFirst=0;
this->edgeCount=0;
this->wage=0;
this->matrix=0;
this->distance=0;
this->predecessor=0;
}
next I have reference in argument of initialize method in FordBellman
void FordBellman::initialize(const AdjacencyMatrix &am)
{
this->vertexCount=am.getVertexCount();
this->vertexFirst=am.getVertexFirst();
this->edgeCount=am.getEdgeCount();
this->wage=am.getWage();
this->matrix=am.getMatrix();
cout << vertexCount;
cout << vertexFirst;
.....
}
in main class I do it in this way
int main() {
AdjacencyMatrix am;
FordBellman fb;
am.createFromFile("matrix.txt");
fb.initialize(am);
}
And if i call fb.initialize(am) console show nothing(should show cout )
Can you tell me what I do wrong ?
repo https://github.com/likoms/Graph/
When I tried to run code from github repository about you sad I got segmentation fault. The reason was in the file FordBellman.cpp line 42. There you didn't allocate array but you used it.
The reason why you didn't see anything is in the fact your program is terminated before it prints something. To be accurate it's happening inside of am.createFromFile("matrix.txt");
Try to write memory allocation for predecessor and I think your code will start working.
I'm a bit confused that you doesn't get message about segmentation fault. What development environment you use?
I have followed a dirextX 9 tutorial on utube and i have tried to modify the program to display multiple triangles based on a set of points. I am using it as a sort of plotter. in my testing i generate a list of points within my plotter class. the plotter class then generates 3 vertices to create a small triangle around the point. the points are then passed to the directx device.
i have moved the code that generates the polygons into my update method, as i need to update the polygon list with fresh polygons.
The code works, but every now and then it will crash with the following error message
Unhandled exception at 0x010F6AF1 in DX3DPlotTest.exe: 0xC0000005: Access violation reading location 0x00000000.
im shure that the problem is to do with the memcpy command being called over and over. i've tried deleting pVert but that creates its own error as pVert is never initiated.
hear is my update version
`
void TestApp::Update(float dt)
{
void *pVerts;
plotter=new Plotter(MaxPoints,0.01f);
float x,y;
for(ULONG i=0;i<MaxPoints;i++)
{
x= (float)(distribution(generator)-2.0f);
y= (float)(distribution(generator)-2.0f);
plotter->Plot(x,y);
}
m_pDevice3D->CreateVertexBuffer(
plotter->listContentCount*sizeof(VertexPositionColor),
0,VertexPositionColor::FVF,
D3DPOOL_MANAGED,
&VB,
NULL
);
//d3d vertex buffer VB
VB -> Lock(0,sizeof(VertexPositionColor)*plotter->listContentCount, (void**)&pVerts, 0);
memcpy(pVerts,plotter->m_pVertexList,sizeof(VertexPositionColor)*plotter->listContentCount);
VB -> Unlock();
}
`
please can someone help me understand how to fix this problem? if been fiddling around with it for hours. It does work, but for a limited amount of time.
Thanks all.
EDIT:
OK now im shure its do to wich recreating my plotter instance
`
Plotter::Plotter(UINT PointCount,float pointsize)
{
listSize = PointCount*3;
listContentCount = 0;
bufferContentCount = 0;
Polycount = 0;
m_pStdtri = new VertexPositionColor[3];
m_pVertexList = new VertexPositionColor[listSize];
m_pStdtri[0] = VertexPositionColor(0.0f ,1.0f*pointsize ,d3dColors::Red);
m_pStdtri[1] = VertexPositionColor(1.0f*pointsize , -1.0f*pointsize ,d3dColors::Lime);
m_pStdtri[2] = VertexPositionColor(-1.0f*pointsize , -1.0f*pointsize ,d3dColors::Red);
}
Plotter::~Plotter()
{
delete(m_pStdtri);
delete(m_pVertexList);
}
void Plotter::Plot(float x, float y)
{
Polycount++;
m_pVertexList[listContentCount]=VertexPositionColor(x+m_pStdtri[0].x, y+m_pStdtri[0].y,d3dColors::Red);
listContentCount++;
m_pVertexList[listContentCount]=VertexPositionColor(x+m_pStdtri[1].x, y+m_pStdtri[1].y,d3dColors::Lime);
listContentCount++;
m_pVertexList[listContentCount]=VertexPositionColor(x+m_pStdtri[2].x, y+m_pStdtri[2].y,d3dColors::Blue);
listContentCount++;
}
`
There are a couple of things that can be wrong here. The plotter object seems to be never disposed, but it is potentially possible that it's done elsewhere. What bothers me, however, is your calling of CreateVertexBuffer over and over again, presumably without ever releasing the resource that you're using. So basically what happens in my opinion is: in every frame, you create a new VertexBuffer. As the memory on your GPU runs low, the command fails eventually, which you don't detect and try to use the "created" buffer, which is not really created. You need to know, that the buffer is not destroyed, even if you delete the object which holds the VB variable. The CreateVertexBuffer command occupies resources on GPU so they need to be explicitly freed when no longer needed. But let's return to the point. This function fails at some point. So it results in a NULL pointer error. My suggestion would be to create the buffer just once and then only update it in each frame. But first, make sure if it is the case.
I have a C++ class Matrix22 with an array and a default constructor:
class Matrix22{
/* something more */
double mat[2][2];
Matrix22(){
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
mat[i][j] = i==j ? 1.0 : 0.0;
}
};
I used it in my program and got a segmentation fault. As the rest was quite difficult and complicated I wrote a simple test routine, that just calls Matrix22(). No more seg fault.
I then ran gdb to debug the problem. If I call the constructor from the separate test routine, gcc reserves some memory for the member mat. I can navigate through the stack and see the return address some bytes after the array.
In the main program the compiler does not reserve enough space. The first element (mat[0][0]) gets written but any futher write just overwrites the next stack frame. I can also verify that as before the constructor the command btreturns a correct backtrace, where after the critical assignment the backtrace is corrupted.
So my question is: Why does in one case the compiler (or the linker?) reserve not enough space for the array, while in the other case that is not happening?
PS: Both "test cases" are compiled with the same compiler and flags and alsolinked against the same object files.
edit:
Here is the "simple" test case that works without seg fault:
void test_Matrix22()
{
Framework::Math::Matrix22 matrix;
}
The code with creates a seg fault is in the class ModuleShaddower (intermixed header and implementation):
class ModuleShaddower{
public:
ModuleShaddower(PVModule& module, const EnvironmentalSetup& setup, const Position& position);
private:
Matrix22 rotMatrix90;
};
ModuleShaddower::ModuleShaddower(PVModule& module, const EnvironmentalSetup& setup, const Position& position)
: module (module), position(position), setup(setup), logger(LoggerFactory::getLoggerInstance())
{
double mat[][2] = {{0, -1},{1, 0}}; // This line will never be reached
rotMatrix90 = Matrix22(mat);
}
As you see, it is quite from within the rest. I will maybe try to extract the problematic code but I think this won't help much.
If your ModuleShaddower contructor code is not getting reached (as per you code comment) then something in your constructor initialization list (related to contructuction of module, possition etc) is causing the problem.
The problem was due to the fact that two object files in different locations had the same name. In the resulting static library, that was created from that object code, sometimes the wrong file gets replaced (both were called Shaddower.o). As I renamed one of the files all went well and no more errors.
I do not know the exact origin of this problem but it is solvable like that.