我使用维基百科的引用
实现了内存占用较少的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来向量并更新为向量元素?
答案 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;