为什么从工厂函数分配向量并在循环中迭代它会导致段错误
Why does assigning a vector from a factory function and iterating over it inside a loop cause a segfault?
我写了一个函数,将一个数字分解为一个较小的数字序列,使得平方序列元素的总和等于输入数字的平方。此函数的声明如下所示:std::vector<long long> Decomp::decompose(long long n);
。为了测试函数的输出,我使用以下main
函数:
int main()
{
for (long long n = 1; n <= 65; ++n)
{
auto res = Decomp::decompose(n);
if (res.empty())
std::cout << n << ": No solution.n";
else
{
std::cout << n << ": [";
for (long long i: res)
std::cout << i << ' ';
std::cout << "b]n";
}
}
}
但是,这会导致n=8
的分段错误:
Output:
1: No solution.
2: No solution.
3: No solution.
4: No solution.
5: [3 4]
6: No solution.
7: [2 3 6]
8: [5 4 3 2 1 0 72405692564177152 72340172838076673 281474993553665 130961 139767842405240 139767842405240 4366240942559068160 72340172838076673 72340172838076673 282578800148737 1099511628033 256 72340168526266368 72340172838091928 72340172838076673 72340172838076673 72340172838076673 72340172838076673 72057594054770689 72340173837828353 72340172838076673 72340172838076673 72340172838076673 72340172838076673 72340172838076673 72405692564177153 72340172838076673 72340172838076673 72340172838076673 72340172838076673 72340172838076673 16843009 240 32 17817984 4 272 32 0 3 304 48 0 4 3 2 72339069014704384 130609 257 130593 0 0 0 0 0 0 282574488404224 72340168543109376 0 0 0 0 0 0 72339069031481344 72339073326448640 72058697861300225 257 0 0 0 0 72057598349672448 72058697861300225 72340172838011137 72058697861366017 282578783305985 65793 0 0 1103806595072 282578783305985 72340172821299457 282578800148737 72340168526332161 72340168543109376 72340172838076673 72339069031481600 282578800148481 72340168526332160 72340168543109376 72340172838076673 72339069031481600 72340172838076673 72340172838076673 72340172838076673 72340172838076673 72339069031481344 72339073326448641 72340172838076673 72057598349737985 72340172838076673 72340172838076673 72340172838076673 282578800148737 130145 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (whole lot of zeros...) Segmentation fault
我怀疑上面的函数main
某些内容导致了段错误,因为以下main
函数似乎工作正常:
int main()
{
long long n = 8;
auto res = Decomp::decompose(n);
if (res.empty())
std::cout << n << ": No solution.n";
else
{
std::cout << n << ": [";
for (long long i: res)
std::cout << i << ' ';
std::cout << "b]n";
}
}
Output:
8: No solution.
编辑:GDB说:
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00000000004026e3 in main ()
Decomp::decompose
看起来像这样:
std::vector<long long> Decomp::decompose(long long n)
{
if (n <= 1)
return std::vector<long long>();
size_t rows = n - 1, cols = n * n + 1;
bool *table = new bool[rows * cols];
std::vector<long long> ret;
for (size_t i = 0; i < rows; ++i)
table[i * cols] = true;
table[1] = true;
for (size_t i = 1; i < rows; ++i)
for (size_t j = 1; j < cols; ++j)
{
table[i * cols + j] = (j < (i + 1) * (i + 1)) ?
table[(i - 1) * cols + j] :
table[(i - 1) * cols + j] ||
table[(i - 1) * cols + j - (i + 1) * (i + 1)];
}
if ( table[rows * cols - 1] )
{
backtrace(n, rows - 1, cols - 1, table, ret);
std::reverse(ret.begin(), ret.end());
}
delete[] table;
return ret;
}
Decomp::backtrace
是一个递归函数,它从 decompose
中创建的表中提取序列,只是将其添加到此处以供参考:
bool Decomp::backtrace(long long n, size_t i, size_t j, bool table[], std::vector<long long> &seq)
{
if (std::inner_product(seq.begin(), seq.end(), seq.begin(), 0LL) == n * n)
return true;
size_t cols = n * n + 1;
if (table[i * cols + j])
{
if ((i + 1) * (i + 1) <= j)
{
seq.push_back(i + 1);
if (backtrace(n, i - 1, j - (i + 1) * (i + 1), table, seq))
return true;
return backtrace(n, i - 1, j, table, seq);
}
else
{
while (table[i * cols + j] and (i + 1) * (i + 1) > j)
--i;
if (table[i * cols + j])
{
seq.push_back(i + 1);
if (backtrace(n, i - 1, j - (i + 1) * (i + 1), table, seq))
return true;
return backtrace(n, i - 1, j, table, seq);
}
else
{
std::cout << "case foundn";
seq.pop_back();
return false;
}
}
}
else
{
seq.pop_back();
return false;
}
}
以及供参考的类标头:
public:
static std::vector<long long> decompose(long long n);
private:
static bool backtrace(long long n, size_t i, size_t j, bool table[], std::vector<long long> &seq);
您的问题在于它返回带有垃圾值的 res 对象auto res = Decomp::decompose(n);
。考虑此输出8: [5 4 3 2 1 0 72405692564177152 72340172838076673.....
0 之后的所有输出似乎都是垃圾值。因此,请提出一些条件并for (long long i: res)
或纠正Decomp::decompose(n)
中断循环。
调试会话后,我发现了问题:bool *table
变量被初始化为以下行中的垃圾值:bool *table = new bool[rows * cols];
。我希望这会将布尔值初始化为 false。非零垃圾值欺骗程序认为有n=8
的解决方案,因此调用backtrace
。但是,backtrace
只有在有解决方案时才有效。否则,索引操作将超出范围。
我通过在表分配中调用 bool
的默认构造函数来修复它,该构造函数将布尔值设置为 false:bool *table = new bool[rows * cols]();
感谢 cantordust 建议尝试断点。
- 编写代码时C++出现错误:错误 1 错误 C2601:'circle':本地函数定义是非法的
- 如何摆脱C ++中的分段错误错误?
- Clang 8 带有静态 constexpr 和数组的链接器错误 - 错误是什么以及如何解决它?
- 为什么每当我尝试运行此链接列表删除功能时都会收到分段错误错误?
- 如何解决分段错误错误C++
- 作为参数模板的模板类:MSVC 错误 - 错误 C2977:模板参数过多 (C++98)
- 安卓工作室 |CPP 文件错误错误: 位图库中对"AndroidBitmap_unlockPixels"的未定义引用
- 卷曲给出分段错误错误
- 无法访问 Arduino 结构字段。错误"退出状态 1。xxxx 不命名类型"
- 错误错误 C2872:"布尔值":kinect.h 的不明确符号
- C++打印模板容器错误(错误:"运算符<<"的不明确重载)理解?
- 结构的分割错误错误
- 为什么此代码返回分段错误错误?
- 错误错误:无法编译内置功能
- 分段错误错误C++
- C++ 1Z 错误:错误:演绎指南中声明中的显式限定
- 使用对数据类型的向量的哈希表中的分段错误错误
- 为什么此代码会导致分段错误错误
- JNA结构字段值错误
- C++段故障错误