[英]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.