简体   繁体   中英

Every few attempts to run my build, I get a segmentation fault. I dont understand why

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 anything 1 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.


1 For 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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM