【发布时间】:2022-01-18 03:26:47
【问题描述】:
我已经用 C++ 实现了一个用于学校的二进制堆类。我在学校 Linux 服务器上运行的程序遇到问题。我的代码在我的 Mac 上 100% 正确输出。从 main.cpp 打印第一行代码后,它出现在 SegFault 中。我曾尝试使用 GDB,但无法确定问题所在。运行 GDB 给我以下问题:程序收到信号 SIGSEGV,分段错误。 std::string::assign(std::string const&) 中的 0x00007ffff7ae8d68。任何试图纠正此问题的帮助将不胜感激。
编辑: 我发现这是导致问题的插入函数:我已将函数更新为:
更新的插入功能:
template <class typ>
void Heap<typ>::insert(typ k) {
if (size == 0) {
size = size + 1;
heap[size] = k;
return;
}
if (size == cap-1) {
cap = cap * 2;
typ *tempHeap = new typ [cap];
for (int i = 1; i <= size; i++)
tempHeap[i] = heap[i];
delete [] heap;
heap = tempHeap;
}
size = size + 1;
heap[size] = k; // insert item at end of heap
int i = size; // set i to size
while (i != 1 && heap[parent(i)] > heap[i]) { // move up to parents until heap property is restored all the way to the root
swapKeys(&heap[parent(i)], &heap[i]); // swap items
i = parent(i); // set i to parent of i
}
}
这修复了正在发生的段错误并正确输出堆。
【问题讨论】:
-
导致失败的最小程序是什么?
-
C++ 程序“有效”并不一定意味着它是正确的并且不受UB 影响。
-
在 OSX 上运行 100% 正确 -- 欢迎来到 C++ 的世界,未定义的行为可能意味着程序似乎可以工作。如果您使用
std::vector<typ> heap;而不是typ *heap;,那么无论您使用什么编译器,如果您使用heap.at(size) = k;而不是heap[size] = k;,您都会看到失败。再一次,使用知道其大小并能够进行边界检查的容器的另一个优势,不同于原始指针和new[]。