簡體   English   中英

每隔幾次嘗試運行我的構建,我就會遇到分段錯誤。 我不明白為什么

[英]Every few attempts to run my build, I get a segmentation fault. I dont 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();
}

這個問題在於本節

 for (it2 = grassEntities.end(); it2 >= grassEntities.begin(); it2--){
    window.render(*it2);
  }

這對我來說很奇怪,因為這部分似乎工作得很好:

  for (it = dirtEntities.end(); it >= dirtEntities.begin(); it--){
    window.render(*it);
  }

在游戲循環內部,在兩個for循環的第一次迭代中, it等於dirtEntities.end()it2等於grassEntities.end() 取消引用end迭代器是未定義的行為。 代碼沒有崩潰的事實只是“幸運”。

如果要反向迭代,請改用反向迭代器:

for (auto it = dirtEntities.rbegin(); it != dirtEntities.rend(); it++){
    window.render(*it);
  }
for (auto it2 = grassEntities.rbegin(); it2 != grassEntities.rend(); it2++){
    window.render(*it2);
  }

.end()返回的迭代器是不可延遲的。 循環應重寫為

for (auto it = dirtEntities.end(); it != dirtEntities.begin();)
{
    --it;
    // ...
}

了解如何在編譯器中啟用迭代器調試。 可以自動檢測到這些錯誤。

vector 的 end() 方法返回一個迭代器,該迭代器引用容器中的最后一個元素。

從這個迭代器中讀取值不是最佳實踐。

如果你想讀取最后一個元素的值,你應該使用 reverse_iterator。

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

rbegin() 將迭代器返回到容器內的最后一個元素。

對我來說很奇怪,因為這部分工作得很好

不,該程序具有未定義的行為,這意味着即使它沒有明確說明並且“似乎正在工作”,它仍然是錯誤的。 這是因為對於第一次迭代,您要取消引用it ,它是調用end返回的迭代器。

//------------vvv---->undefined behavior for the first iteration
window.render(*it);

未定義的行為意味着任何事情1都可能發生,包括但不限於給出預期輸出的程序。 永遠不要依賴(或基於)具有未定義行為的程序的輸出。 該程序可能會崩潰。

所以你看到的輸出(也許看到)是未定義行為的結果。 正如我所說,不要依賴具有 UB 的程序的輸出 該程序可能會崩潰。

因此,使程序正確的第一步是刪除 UB。 只有這樣,您才能開始推理程序的輸出。


1有關未定義行為的更技術上准確的定義,請參見此處,其中提到:對程序的行為沒有限制

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM