神秘的海森虫?
所以我正在制作一个带有传送和普通鼠标的贪吃蛇游戏。我有一个这样运行的循环:
while(snake.alive() && miceEaten < micePerLevel)
{
displayInfo(lives, score, level, micePerLevel - miceEaten);
//some code
if(miceEaten())
{
//update score...
}
//more stuff...
}
上面代码的问题是 displayInfo
在分数更新之前被调用,因此在吃掉鼠标后,用户必须等到循环再次运行才能查看他的分数更新。所以我将这一行代码移到了函数的底部:
while(snake.alive() && miceEaten < micePerLevel)
{
//some code
if(miceEaten())
{
//update score...
}
//more stuff...
displayInfo(lives, score, level, micePerLevel - miceEaten);
}
传送停止工作!每当蛇到达传送点时,程序就会崩溃。 displayInfo
使用以下代码:
stringstream s;
s << "LEVEL " << left << setw(12) << level << "LIVES: " << setw(12) << lives << "MICE LEFT: " << setw(12) << miceLeft
<< "SCORE: " << setw(13) << score;
printLine(0, s.str(), WHITEONBLUE);
其中 printLine
只有 color_set
、mvprintw
和 refresh( )
。与传送无关。诡异的。
因此,我转到了 Snake 函数,蛇从传送中获取下一个位置:
body.push_back(teleports[overlap(next)]->teleportFrom(dir)); //next is a Location object
其中 teleports[overlap(next)]->teleportFrom(dir)
返回蛇要传送到的位置。为了找出崩溃的原因(也许 Teleport
返回屏幕外的某个位置?),我在上面的行之前添加了以下 3 行:
Location l = teleports[overlap(next)]->teleportFrom(dir);
mvprintw(1, 0, "(%i, %i)", l.x, l.y);
refresh();
问题就消失了!
不仅如此,我还必须拥有这三行。如果我注释掉 mvprintw(1, 0, "(%i, %i)", lx, ly);
或 refresh();
或两者,则程序在到达传送时像以前一样崩溃。
关于可能导致这种行为的原因有什么想法吗?
更新:我尝试删除所有警告(主要是有关有符号/无符号数字比较的警告),但到目前为止仅保留 1 个:
warning: reference to local variable 'other' returned
代码:
Location& Location::operator = (Location other)
{
if(this == &other)
return other;
x = other.x;
y = other.y;
return *this;
}
我该怎么做才能修复此警告?
So I'm making a snake game with teleports and the usual mice. I had a loop running like this:
while(snake.alive() && miceEaten < micePerLevel)
{
displayInfo(lives, score, level, micePerLevel - miceEaten);
//some code
if(miceEaten())
{
//update score...
}
//more stuff...
}
The problem with the above code was that displayInfo
gets called before the score gets updated, and so after eating a mouse, the user has to wait until the loop runs again to see his score updated. So I moved that one line of code to the bottom of the function:
while(snake.alive() && miceEaten < micePerLevel)
{
//some code
if(miceEaten())
{
//update score...
}
//more stuff...
displayInfo(lives, score, level, micePerLevel - miceEaten);
}
and teleports stop working! The program crashes whenever the snake reaches a teleport. And displayInfo
uses the following code:
stringstream s;
s << "LEVEL " << left << setw(12) << level << "LIVES: " << setw(12) << lives << "MICE LEFT: " << setw(12) << miceLeft
<< "SCORE: " << setw(13) << score;
printLine(0, s.str(), WHITEONBLUE);
Where printLine
only has a color_set
, mvprintw
, and refresh()
. Nothing to do with Teleports. Weird.
So I went to the snake function where the snake gets its next location from a teleport:
body.push_back(teleports[overlap(next)]->teleportFrom(dir)); //next is a Location object
Where teleports[overlap(next)]->teleportFrom(dir)
returns the location the snake is to be teleported to. In an attempt to see why it was crashing (perhaps Teleport
was returning some location offscreen?), I added the following 3 lines before the above line:
Location l = teleports[overlap(next)]->teleportFrom(dir);
mvprintw(1, 0, "(%i, %i)", l.x, l.y);
refresh();
And the problem disappears!
Not only that, but I HAVE to have those three lines. If I comment out mvprintw(1, 0, "(%i, %i)", l.x, l.y);
, or refresh();
, or both, the program crashes as before upon reaching a teleport.
Any ideas on what might be causing this behavior?
UPDATE: I tried removing all warnings (which were mostly warnings about comparisons of signed/unsigned numbers), but only 1 remains so far:
warning: reference to local variable 'other' returned
And the code:
Location& Location::operator = (Location other)
{
if(this == &other)
return other;
x = other.x;
y = other.y;
return *this;
}
What do I do to fix this warning?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
像这样构建你的赋值运算符:
您应该始终返回 *this (即使它们相等)。但自从您创建本地副本以来,他们永远不会这样做(所以这不是您的错误)。
对于这样一个简单的类来说,标准的复制和交换似乎有点大材小用。
附言。您应该修复所有警告(即使它们像无符号不匹配一样简单)。如果您不修复它们,您将对其效力免疫,并且不会发现真正的问题,因为它周围都是您忽略的警告。因此,请修复所有这些问题(我总是打开标志,使编译器将所有警告视为错误,这样如果有任何警告,代码就不会编译)。
实现赋值运算符的正确方法(或者最普遍接受的好方法)。就是使用复制和交换习惯用法:
Build your assignment operator like this:
You should always return *this (even if they were equal). But they never would since you were creating a local copy (so this was not your error).
The standard copy and swap seemed a bit overkill for such a simple class.
PS. You should fix all warnings (even if they are as simple as the unsigned mismatch). If you do not fix them you will become immune to their potency and will not spot a real problem because it is surrounded by warning that you are ignoring. So fix them all (aI always turn on the flag that makes the compiler treat all warnings as errors so that the code does not compile if there are any warnings).
The correct way to implement assignment operator (or the most commonly accepted good way). Is to use the copy and swap idiom:
这将返回一个引用。当函数返回时,
other
会发生什么? (它死了,而您没有提及任何内容。)由于这是您在问题区域周围处理的类,因此这可能就是原因。重新排列周围的代码会使堆栈处于某种条件下,在这种条件下引用死变量“有效”。将其更改为
return *this
,或者干脆删除该检查。 (在现代 CPU 上,在没有分支的情况下分配两个变量可能总是比添加分支运行得更快。)(通常还应该通过引用而不是通过值获取参数。)
This returns a reference. When the function returns, what happens to
other
? (It dies, and you're referring to nothing.) Since this is the class you're dealing with around the problem area, this is probably the cause. Re-arranging surrounding code leaves the stack in a certain condition where referring to the dead variable "works".Change it to
return *this
, or just remove the check altogether. (Assigning two variables without a branch will probably always run faster than adding a branch, on a modern CPU.)(You should also generally take the parameter by reference, instead of by-value.)
您检查过导致此异常的代码吗?这里引用的 Heisenbug 现象:
以下是一些准则:
另一句话:
确保开关已关闭 - 无优化、完整调试信息、清除任何现有版本、重新启动 IDE 并再次重新编译...
Have you checked your code that is causing this anomaly? The Heisenbug phenomena quoted here:
Here are a few guidelines:
Another quote:
Ensure that the switches are turned off - no optimization, full debug information, clear any existing builds, restart the IDE and recompile again....
首先,您的 Location::operator= 应该像这样:
但是,这可能无法解释崩溃。在大多数体系结构上,堆栈上的错误指针不会崩溃(假设 x 和 y 是 int)。
那么,这是曼德尔虫,而不是海森虫。你有其他人在某个地方破坏了记忆。祝你好运。
First of all, your Location::operator= should be like this instead:
However, that probably doesn't explain the crash. Bad pointers on stack here don't crash on most architectures (assuming x and y are int).
Now then, this is a mandelbug, not a heisenbug. You have somebody else somewhere corrupting memory. Good luck.