C++程序在调试和发布模式下给出了不同的结果

C++ program gives different results in Debug and Release mode

本文关键字:结果 模式 调试 程序 布模式 C++      更新时间:2023-10-16

我正在做一些算法练习,遇到了一个奇怪的问题。我写了下面的代码来解决这个问题http://main.edu.pl/en/archive/oi/21/pta.我测试了它,它看起来在调试模式下运行良好,但一旦我切换到Release(或将其提交到网站),它就会对一些测试给出错误的答案。

例如9e.in(我在这里上传了这个测试:https://www.dropbox.com/s/ki4vfk2p5140xwo/pta9e.in?dl=0)我从Debug构建中得到的答案是正确的:

255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255

然而,在发布(和提交到网站后)我得到:

543
530
530
530
530
530
543
530
530
530
543
530
530
543
530
530
530
543
530
530
543
530
530
530
530

我不知道是什么导致了这个问题:/这是我的代码:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdlib>
#include <queue>
#include <cmath>
#include <stdio.h>
using namespace std;
int numOfTrees = 0;
int* trees = NULL;
int numOfBirds = 0;
int computeBird(int birdStamina)
{
    int tired = 0;
    int position = 0;
    int lastTree = 0;
    while (true)
    {
        if (position >= numOfTrees - 1)
        {
            return tired;
        }
        lastTree = trees[position];
        int furthestGoodTree = -1;
        int tallestTreePos = position + birdStamina;
        if (tallestTreePos > numOfTrees - 1)
        {
            tallestTreePos = numOfTrees - 1;
        }
        int tallestTreeSize = trees[tallestTreePos];
        for (int n = 1; n <= birdStamina; ++n)
        {
            int pos = position + n;
            if (pos >= numOfTrees)
                break;
            if (trees[pos] < lastTree)
            {
                if (trees[pos] >= trees[furthestGoodTree])
                {
                    furthestGoodTree = pos;
                }
            }
            if (trees[pos] >= tallestTreeSize)
            {
                tallestTreeSize = trees[pos];
                tallestTreePos = pos;
            }
        }
        if (furthestGoodTree != -1)
        {
            position = furthestGoodTree;
        }
        else
        {
            position = tallestTreePos;
            tired++;
        }
    }
}
int main()
{
    scanf("%d", &numOfTrees);
    trees = new int[numOfTrees + 2];
    int val = 0;
    for (int n = 0; n < numOfTrees; ++n)
    {
        scanf("%d", &val);
        trees[n] = val;
    }
    scanf("%d", &numOfBirds);
    int* cache = new int[numOfTrees + 2];
    for (int n = 0; n < numOfTrees; ++n)
    {
        cache[n] = -1;
    }
    int results[30];
    int birdStamina = 0;
    for (int n = 0; n < numOfBirds; ++n)
    {
        scanf("%d", &birdStamina);
        if (cache[birdStamina] != -1)
        {
            results[n] = cache[birdStamina];
        }
        else
        {
            int result = computeBird(birdStamina);
            cache[birdStamina] = result;
            results[n] = result;
        }
    }
    for (int n = 0; n < numOfBirds; ++n)
    {
        printf("%dn", results[n]);
    }
    //system("pause");
    return 0;
}

这段代码真的应该有我添加的断言

       if (trees[pos] < lastTree)
        {
            assert( furthestGoodTree >= 0 );
            if (trees[pos] >= trees[furthestGoodTree])
            {
                furthestGoodTree = pos;
            }
        }

据我所知,这种情况是依赖于数据的,不是由其他代码强制的,当然也不是由任何本地代码强制的。

当您依赖某个条件为true,并且在本地不清楚为什么它应该为true时,您应该有一个assert,这样调试运行就会注意到不正确的假设。

我不确定您输入了什么输入数据,但在我看来,您似乎超出了数组的边界。例如,您将缓存分配为numOfTrees的数组,但稍后通过索引numOfBirds读取它。我假设发布版本和调试版本具有不同的内存分配,因此您的越界读取会给您带来不同的结果。