Visual Studio 2017 C ++调试/发布不同的输出

时间:2018-05-17 12:11:07

标签: c++11 visual-studio-2017 stdvector

我使用维基百科的引用

实现了内存占用较少的Kolakoski's sequence
#include <iostream>
#include <iomanip>
#include <vector>

int IncrementPointer(std::vector<int>& vec, int k)
{
    if (vec.size() <= k)
    {
        vec.push_back(22);
    }

    if (vec[k] == 11)
    {
        vec[k] = 1;
        return 1;
    }
    else if (vec[k] == 22)
    {
        vec[k] = 2;
        return 2;
    }
    else if (vec[k] == 1)
    {
        vec[k] = IncrementPointer(vec, k + 1) == 1 ? 2 : 22;
        return 2;
    }
    else if (vec[k] == 2)
    {
        vec[k] = IncrementPointer(vec, k + 1) == 1 ? 1 : 11;
        return 1;
    }

    return 0;
}

int main()
{
    long long iteration = 2;
    long long nextPowOf10 = 10;

    long long numOf1s = 1;

    std::vector<int> vec;

    std::cout << std::setw(15) << 'n' << std::setw(15) << "#1s" << std::setw(8) << "P(n)\n";
    std::cout << std::setw(15) << 1 << std::setw(15) << numOf1s << '\n';

    while (iteration++ <= 100'000'000'000'000)
    {
        int retvalue = IncrementPointer(vec, 0);
        if (retvalue == 1)
            ++numOf1s;
        if (iteration % nextPowOf10 == 0)
        {
            std::cout << std::setw(15) << nextPowOf10 << std::setw(15) << numOf1s << std::setw(8) << vec.size() << '\n';
            nextPowOf10 *= 10;
        }
    }
    return 0;
}

现在,程序在内部计算调试模式中序列的正确元素并输出预期结果。到目前为止,非常好。

问题从发布模式开始,矢量被优化掉了(怎么可能?),而现在计算的元素是错误的。

预期序列为[[1 2] 2 1 1 2 1 2 2等],前两个是预设的。 在释放模式中元素是[1 2] 2 1 1 1 1 1 2 ......显然,出现了错误。然后输出是意外的,程序崩溃,调用malloc(所以它确实有一个地方向量重新分配)。

我做错了什么?它是否同步push_back来向量并更新为向量元素?

1 个答案:

答案 0 :(得分:2)

我相信这样的结构表现出不确定的行为:

vec[k] = IncrementPointer(vec, k + 1) == 1 ? 2 : 22;

未指定首先评估vec[k]IncrementPointer(vec, ...)vec[k]返回对相应元素的引用。如果稍后调用IncrementPointer,它可能会将新元素推送到vec,这反过来可能导致它重新分配,于是该引用变为悬空。

成功

int val = IncrementPointer(vec, k + 1);
vec[k] = val == 1 ? 2 : 22;