简体   繁体   English

每隔几次尝试运行我的构建,我就会遇到分段错误。 我不明白为什么

[英]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.所以我得到一个 Segmentation fault: 11 错误,我知道是哪个块导致它,但我试图理解为什么。

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() .在游戏循环内部,在两个for循环的第一次迭代中, it等于dirtEntities.end()it2等于grassEntities.end() Dereferencing end iterators is undefined behaviour.取消引用end迭代器是未定义的行为。 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. .end()返回的迭代器是不可延迟的。 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. vector 的 end() 方法返回一个迭代器,该迭代器引用容器中的最后一个元素。

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.如果你想读取最后一个元素的值,你应该使用 reverse_iterator。

std::vector<int>::reverse_iterator rit = myvector.rbegin();

rbegin() returns you the iterator to the last element inside the container. rbegin() 将迭代器返回到容器内的最后一个元素。

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 .这是因为对于第一次迭代,您要取消引用it ,它是调用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.未定义的行为意味着任何事情1都可能发生,包括但不限于给出预期输出的程序。 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.正如我所说,不要依赖具有 UB 的程序的输出 The program may just crash.该程序可能会崩溃。

So the first step to make the program correct would be to remove UB.因此,使程序正确的第一步是删除 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 . 1有关未定义行为的更技术上准确的定义,请参见此处,其中提到:对程序的行为没有限制

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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