C++出现奇怪问题

5

我有一个函数,可以创建并插入一些数字到一个向量中。

    if(Enemy2.dEnemy==true)
    {
        pt.y=4;
        pt.x=90;
        pt2.y=4;
        pt2.x=125;
        for(int i=0; i<6; i++)
        {
            Enemy2.vS1Enemy.push_back(pt);
            Enemy2.vS2Enemy.push_back(pt2);
            y-=70;
            pt.y=y;
            pt2.y=y;
        }
        Enemy2.dEnemy=false;
        Enemy3.cEnemy=0;
    }

需要在两个向量中插入6个数字,唯一的问题是它实际上插入了更多的数字。

我认为如果Enemy2.dEnemy == true,则代码片段不会运行,并且它不会一直保持为真。

代码片段第一次运行时,Enemy2.dEnemy被设置为false,并且不应再次运行。

我没有在任何地方将Enemy2.dEnemy设置为true,除非在创建窗口时。

如果我在代码片段的任何位置插入断点,则程序将正常工作 - 它将仅在两个向量中插入6个数字。

这里有什么问题呢?


好的,所以我进行了一些调试。
我发现Enemy2.dEnemy=false;由于某种原因被跳过了。
我尝试这样做来查看是否是这样。

 if(Enemy2.dEnemy)
    {
        pt.y=4;
        pt.x=90;
        pt2.y=4;
        pt2.x=125;
        for(int i=0; i<6; i++)
        {
            Enemy2.vS1Enemy.push_back(pt);
            Enemy2.vS2Enemy.push_back(pt2);
            y-=70;
            pt.y=y;
            pt2.y=y;
        }
        TCHAR s[244];
        Enemy2.dEnemy=false;
        if(Enemy2.dEnemy)
        {
          MessageBox(hWnd, _T("0"), _T(""), MB_OK);
        }
        else
        {
            MessageBox(hWnd, _T("1"), _T(""), MB_OK);
        }
        Enemy3.cEnemy=0;
    }

提示框弹出显示1,我的代码正常工作。似乎Enemy2.dEnemy=false;没有时间运行;/
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah! 好的,我找到了真正的问题所在,这个问题导致插入超过6个数字... 问题出在我分配Enemy2.dEnemy=true;处。

if(Enemy2.e1)
{
Enemy2.now=time(NULL);
Enemy2.tEnemy=Enemy2.now+4;
Enemy2.e1=false;
}
if(Enemy2.tEnemy==time(NULL))
{
check=1;
Enemy2.aEnemy=0;
Enemy2.dEnemy=true;
}

问题似乎是第二个 if 语句运行了多次,这很奇怪!

请澄清:代码有什么问题? - Alexander Rafferty
是C++本身有问题还是C++代码有问题? - Chubsdad
1
你是否正在使用多个线程? - Jonathan
这里没有足够的上下文来解释正在发生什么-每当该代码运行时,它将恰好推入六个点到这些向量中。可能你的问题在它之外的某个地方。 - Peter
这可能是使用经过验证的“std::cout”调试方法的时候了 :) 每次发生 push_back 时都输出一些内容。有12个输出吗?如果是,那么很奇怪。如果不是...那就加入更多的 couts!只要审慎并确保您的代码不会因额外的控制台输出而开始表现出不同的行为即可 :) - Doug T.
我按照你说的做了一些事情,看起来有数百万个。 - Ramilol
2个回答

3

首先,摆脱那个可怕的if (Enemy2.dEnemy == true) - 应该改为:

if (Enemy2.dEnemy)

我喜欢给我的布尔值取一个可读的句子段,比如Enemy2.isABerserkerEnemy3.hasHadLeftLegCutOffThreeInchesBelowTheKnee,但这只是个人偏好。
除此之外,我唯一能建议的就是线程问题。该代码本身没有问题,但存在两个线程可能同时进入if语句并开始将值推入你的向量的情况。
换句话说,如果线程1在执行推送时,线程2遇到了if语句,线程2也会开始推送值,因为线程1尚未将dEnemy设置为true。不要认为将赋值移到if块的顶部就可以解决问题 - 这只能减少但不能完全消除问题窗口。
我的建议是,在向量中有六个以上条目的情况下打印出其内容,这可能会提示发生了什么事情(如果您愿意,请在此处发布输出)。
关于您更新的第二个if运行两次的问题:
if(Enemy2.e1)
{
Enemy2.now=time(NULL);
Enemy2.tEnemy=Enemy2.now+4;
Enemy2.e1=false;
}
if(Enemy2.tEnemy==time(NULL))
{
check=1;
Enemy2.aEnemy=0;
Enemy2.dEnemy=true;
}

如果在同一秒内两次执行此代码(这并非不可能),第二个if语句将会运行两次。 这是因为time(NULL)给出的是自纪元以来经过的秒数,所以在那一秒结束之前,您很可能会执行该if中的内容成千上万次(甚至更多)。

2
推荐不要使用“if (condition==true)”这种用法,否则我会想尖叫。 - Kristopher Johnson
@paxdiablo,Kristopher Johnson:请问你们能分享更多关于这个习语的信息吗? - Chubsdad
2
@chubsdad,condition是一个布尔值。如果你将它与true进行比较,你会在哪里停止呢?归谬法规定你不应该停止,这导致了一些奇妙的事情,比如if ((!((x == true) == true) == false) == true) ... :-) 请参见https://dev59.com/hHRC5IYBdhLWcg3wG9Xp#404846 - paxdiablo
@Ramiz,你可能_认为_你的游戏只使用了一个线程。但是你的操作系统可能有其他想法 :-) 在if语句中放置一些代码,将一行追加到临时文件或增加一个全局整数,然后再打印 - 这是你唯一可以确定的方法。 - paxdiablo
我不知道该怎么做才能将一行内容追加到临时文件中或者增加它。 - Ramilol

1

如果在您放置断点或诊断输出消息时此问题消失,那么这是一个强烈的线索表明问题是未定义行为,通常是由于像解除初始化指针或粗心使用const_cast之类的东西引起的。

问题的原因可能与您正在查看的代码无关。它是在其他地方引起的,只是碰巧在这里显示出来。就像有人被掉落的砖块击中:明显的症状是一个躺在人行道上昏迷不醒的人,但真正的问题与这个人或人行道无关,而是几层楼上。

如果您想找到错误的原因,请删除您的诊断,直到问题重新出现,然后开始删除所有其他内容。修剪掉所有其他代码。每当错误停止时,请回退到它再次开始的位置;如果您没有看到错误的原因,请从其他地方开始修剪。最终,错误将无处可藏。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接