I'm having problem with a copying method in a simple C++ program.
Everytime I call copy:
Sudoku::SudokuNode** Sudoku::copy(SudokuNode** sudokuBoard)
{
SudokuNode** tempSudokuBoard = new SudokuNode*[9];
for(int i = 0; i<9; i++)
{
tempSudokuBoard[i] = new SudokuNode[9];
for(int j = 0; j<9; j++)
{
tempSudokuBoard[i][j].currentInteger = sudokuBoard[i][j].currentInteger;
for(vector<int>::iterator iter = sudokuBoard[i][j].possibleIntegers.begin(); iter!= sudokuBoard[i][j].possibleIntegers.end();)
{
tempSudokuBoard[i][j].possibleIntegers.push_back(*iter);
}
}
}
return tempSudokuBoard;
}
The program seems to completely halt, not returning a a visible error.
If I try to debug the program, the debugger works fine until I arrive at the copy method. Then the debugger displays a dialog box saying:
There is no source code available for the current location.
Any idea what is wrong?
for(vector<int>::iterator iter = sudokuBoard[i][j].possibleIntegers.begin(); iter!= sudokuBoard[i][j].possibleIntegers.end();)
You don't seem to be advancing the iterator in that loop, so it will never end. Add ++iter to the counting expression (after the last ; in the for loop).
As to why your debugger can't find source for that location, that's platform dependent. What debugger are you using?
You do not increase the iterator on the inside loop:
for(vector<int>::iterator iter = sudokuBoard[i][j].possibleIntegers.begin(); iter!= sudokuBoard[i][j].possibleIntegers.end(); ++iter)
Resulting an infinate for loop (Compiler knows this and "optimized" it for an infinite loop, which is why there is no code available).
I suggest you recode it to use ...
class SudokuBoard
{
SudokuNode nodes[9];
};
Related
So i'm getting a Segmentation fault: 11 error and I know which block is causing it, but i'm trying to understand why.
std::vector<Entity> grassEntities;
for (int i = 0; i < 40; i++) {
grassEntities.push_back(Entity(i * 32, 592, grassTexture));
}
std::vector<Entity> dirtEntities;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 41; j++) {
dirtEntities.push_back(Entity(j * 32, (688 - (i * 32)), dirtTexture));
}
}
bool gameRunning = true;
SDL_Event event;
while (gameRunning) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
gameRunning = false;
}
window.clear();
std::vector<Entity>::iterator it;
std::vector<Entity>::iterator it2;
for (it = dirtEntities.end(); it >= dirtEntities.begin(); it--){
window.render(*it);
}
for (it2 = grassEntities.end(); it2 >= grassEntities.begin(); it2--){
window.render(*it2);
}
window.display();
}
this issue lies with this section
for (it2 = grassEntities.end(); it2 >= grassEntities.begin(); it2--){
window.render(*it2);
}
which for me is odd because this section seemed to work just fine:
for (it = dirtEntities.end(); it >= dirtEntities.begin(); it--){
window.render(*it);
}
Inside the game loop, in the first iteration of both for loops, it is equal to dirtEntities.end() and it2 is equal to grassEntities.end(). Dereferencing end iterators is undefined behaviour. The fact that the code doesn't crash is just "lucky".
If you want to iterate in reverse, use reverse iterators instead:
for (auto it = dirtEntities.rbegin(); it != dirtEntities.rend(); it++){
window.render(*it);
}
for (auto it2 = grassEntities.rbegin(); it2 != grassEntities.rend(); it2++){
window.render(*it2);
}
The iterator returned by .end() is not defererencable. The loop should be rewritten as
for (auto it = dirtEntities.end(); it != dirtEntities.begin();)
{
--it;
// ...
}
Learn how to enable iterator debugging in your compiler. Those kind of errors can be detected automatically.
The end() method from vector returns an iterator referring to the past-the-end element in the container.
It is not the best practice to read the value from this iterator.
If you want to read the value of the last element you should use reverse_iterator instead.
std::vector<int>::reverse_iterator rit = myvector.rbegin();
rbegin() returns you the iterator to the last element inside the container.
for me is odd because this section works just fine:
No, the program has undefined behavior meaning it is still in error even if it doesn't say so explicitly and "seems to be working". This is because for the very first iteration you're dereferencing it which is the iterator returned by the call to end.
//------------vvv---->undefined behavior for the first iteration
window.render(*it);
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.
So the output that you're seeing(maybe seeing) is a result of undefined behavior. And as i said don't rely on the output of a program that has UB. The program may just crash.
So the first step to make the program correct would be to remove UB. Then and only then you can start reasoning about the output of the program.
1For a more technically accurate definition of undefined behavior see this, where it is mentioned that: there are no restrictions on the behavior of the program.
I have this code which is supposed to look for elements present in all vectors in a std::vector<std::vector<int>>:
for(int x = 0;x < list.size();x++){
for(int y = 0;y < list[x].size();y++){
std::vector<std::vector<int>::iterator> ptr;
for(int z = 1;z < list.size();z++){
std::vector<int>::iterator iter = std::find(list[z].begin(),
list[z].end(), list[x][y]);
if(iter != list[z].end()){
ptr.push_back(iter);
}else
goto fail;
}
list[0].erase(list[0].begin() + y);
for(int z = 1;z <= ptr.size();z++){
list[z].erase(ptr[z - 1]);
}
fail: continue;
}
}
The program always produces wrong output and randomly crashes. Debugging shows that it receives SIGTRAP when deconstructing list in ntdll. This happens randomly, but the program never works correctly. I don't have any breakpoints in the code.
These are the errors I found in the code some time after asking this question:
The code for determining which iterator is from which array was designed only for list[0], instead of being designed for list[x], causing erase() being called with iterators belonging to another vector, causing memory corruption.
x was replaced with 0 in some places (forgot to change it).
list was being corrupted by other code in the program (fixed now).
These are the fixes:
Used an iterator to std::vector<std::vector<int>::iterator> and if(z==x)continue;else{list[z].erase(*iter); iter++;} to make sure iter always points to the correct element.
Replaced 0 with x.
Fixed problems in other places in the program.
The program works correctly now, thanks for trying to help me.
I sometimes get this type of errors. My question is, is there a way to find out information about when and where(which line) exactly this error occurs? I'm on ubuntu linux 14.04. Using sublime and g++.
Here is my current code. I get a floating point exception in this. It takes 2 vectors and prints the numbers that are divisible by every element of the first set and can divide every element of the second set.
Posting the code is kinda irrelavant to the topic but it forced me to find a decent way to debug the mentioned error types. This is my first time asking a question here, go easy on me.
int main()
{
vector<int> firstVector;
vector<int> secondVector;
firstVector = {2,4};
secondVector = {16,32,96};
auto it = firstVector.begin();
for (int i = 1; i <= 100; ++i)
{
it = firstVector.begin();
for (; ; ++it)
{
if(i%(*it)!=0)
break;
if(it==firstVector.end())
{
it=secondVector.begin();
while(it!=secondVector.end())
{
if((*it)%i!=0)
{
it=firstVector.begin();
break;
}
it++;
}
}
if(it==secondVector.end())
break;
}
if(it==secondVector.end())
cout << i << endl;
}
return 0;
}
I guess there is a problem in iteration over firstVector and secondVector. In second loop:
auto it = firstVector.begin();
for (; ; ++it)
{
it is iterator for firstVector. But in the next loop:
it=secondVector.begin();
while(it!=secondVector.end())
{
it becomes iterator for the secondVector. Iteration over it continues in the outer for loop after this while loop. You increment ++it and access elements if(i%(*it)!=0) at and after the .end() element. This leads to UB:
This element acts as a placeholder; attempting to access it results in undefined behavior.
This question is kind of a two-parter. Since Nikita already addressed your code...
My question is, is there a way to find out information about when and where(which line) exactly this error occurs?
Use gdb name-of-executable to debug on Linux. Simply run and the program will break when a seg fault occurs or, I believe, a fatal exception is thrown. It will tell you the file name and line number.
You can also look up more gdb commands, like here: http://www.yolinux.com/TUTORIALS/GDB-Commands.html
I am reading a tutorial about joystick input handling with SDL and I am struggling with a part of the code.
In .h file I got:
std::vector<std::pair<Vector2D*, Vector2D*> > m_joystickValues;
and in .cpp file I got:
m_joystickValues.push_back(std::make_pair(new Vector2D(0,0),new Vector2D(0,0)));
In this case I have one joystick, if there is many joysticks there will more push_backs, I want to access the adresses in "m_joystickValues" so I can delete them in a clean function.
Anyone has an idea how I can do this with a for loop. Thanks
For example you can use the range-based for statement
for ( auto &p : m_joystickValues )
{
delete p.first;
delete p.second;
}
The same can be done using the ordinary for statement
for ( size_t i = 0; i < m_joystickValues.size(); i++ )
{
delete m_joystickValues[i].first;
delete m_joystickValues[i].second;
}
Or you can use standard algorithm std::for_each with an appropriate lambda-expression. It is similar to using a for statement with iterators.
for(int i = 0; i < m_joystickValues.size(); i++)
{
m_joystickValues[i] //do something with this
}
Is this what you are looking for? Also, you could use the at function, since it is more safe.
for(auto& i : m_joystickValues)
{
delete i.second;
delete i.first; // or do whatever
}
At end of the loop you can erase the entire vector
m_joystickValues.erase(m_joystickValues.begin(), m_joystickValues.end());
I've recently inherited a project primarily done in C++, so this is my first real exposure to it. I'm wondering if I may have a problem erasing a vector's elements from within a loop bounded by the vector's begin() and end().
Here's (essentially) what I've been trying to do:
for (vector<double>::iterator i = distance.begin(); i < distance.end(); i++) {
for (vector<double>::iterator j = i + 1; j < distance.end(); j++) {
/* code to assemble *i, *j, and some other values, say *x & *y
(also iterators) assumed to be in the distance vector */
vector< vector<double >::iterator remove;
remove.push_back(i); remove.push_back(j);
remove.push_back(x); remove.push_back(y);
sort(remove.begin(), remove.end());
for (int r = remove.size() - 1; r >= 0; r--) {
distance.erase(remove.at(r));
}
}
}
For what I'm testing it on, this appears to work. However, I'm concerned that's just because of a fluke and this solution shouldn't be used. Does distance.end() get reset at the beginning of each loop, or does C++ just check with the initial value?
for-loop will evaluate i < distance.end() on each loop. The problem is in distance.erase, it will invalidate i, so the result of i++ is undefined.
distance.end() is always accurate to the current state of the vector.
for() loops always re-evaluate the condition on every loop.