с ++ странная проблема - PullRequest
       15

с ++ странная проблема

5 голосов
/ 07 сентября 2010

У меня есть функция, которая создает и вставляет некоторые числа в вектор.

    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; не успевает бежать; /
бла-блаб-блах-блах-блах-блах-блах-блах-блах-блах-блах-блах-блах!хорошо, я нашел, где настоящая проблема, которая заставляла вставлять более 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;
}

проблема кажется, что второй, если выполняется более одного раза,что странно!

Ответы [ 2 ]

3 голосов
/ 07 сентября 2010

Перво-наперво: избавьтесь от этого отвратительного if (Enemy2.dEnemy == true) - оно должно быть:

if (Enemy2.dEnemy)

(я также предпочитаю называть мои логические значения в виде читаемых предложений, таких как Enemy2.isABerserker или Enemy3.hasHadLeftLegCutOffThreeInchesBelowTheKneeно это всего лишь личные предпочтения).

Кроме этого, единственное, что я могу предложить, это проблема с многопоточностью.В этом коде нет ничего плохого как такового, но есть окно, в котором два потока могут ввести оператор if, и оба начнут помещать значения в ваш вектор.

Другими словами, если поток 1 выполняетнажатие, когда поток 2 встречает оператор if, поток 2 также начнет выдавать значения, поскольку потоку 1 еще предстоит установить dEnemy в true.И не думайте, что вы можете просто переместить назначение в верхнюю часть блока if - это уменьшит, но не удалит окно.

Мой совет - распечатать содержимоевекторов в ситуации, когда у них более шести записей, и это может дать подсказку о том, что произошло (опубликуйте выходные данные здесь, если хотите).


Re ваше обновление, что второе 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 тысяч раз (или больше).

1 голос
/ 07 сентября 2010

Если эта проблема исчезает, когда вы вводите точку останова или диагностическое выходное сообщение, это явный признак того, что проблема заключается в неопределенном поведении, которое обычно вызывается чем-то вроде разыменования неинициализированного указателя или небрежного использования const_cast.

Причина проблемы, вероятно, не имеет ничего общего с кодом, который вы просматриваете. Это вызвано где-то еще и просто появляется здесь. Это похоже на то, как кого-то ударило падающим кирпичом: очевидный симптом - это человек, лежащий без сознания на тротуаре, но настоящая проблема не имеет ничего общего с человеком или тротуаром, это несколько историй вверх.

Если вы хотите найти причину ошибки, удаляйте диагностику, пока проблема не появится снова, затем начните удалять все остальное . Удалите весь другой код. Всякий раз, когда ошибка прекращается, выполняйте резервное копирование до ее повторного запуска; если вы не видите причину ошибки, начните обрезку в другом месте. В конце концов, ошибке будет негде спрятаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...