C++ C++;删除指针数组中的第一个元素会影响后面的元素

C++ C++;删除指针数组中的第一个元素会影响后面的元素,c++,arrays,heap,delete-operator,sigabrt,C++,Arrays,Heap,Delete Operator,Sigabrt,对于实验室作业,我正在研究堆的数组实现。我有一个类型为PrintJob*的数组。我面临的问题是,我尝试使用delete删除的第一个元素arr[0]奇怪地修改了数组的第二个元素。最后,该元素到达堆的头部,删除它会导致SIGABRT 我最初认为可能是直接从数组中删除它,delete arr[0]发出了某种类型的错误,因为我会反复调用delete arr[0];尽管如此,我还是在删除后立即用它的下一个最大的子级更新了arr[0]。因此,我尝试将其存储到临时变量中,然后删除它: void出列(){ Pr

对于实验室作业,我正在研究堆的数组实现。我有一个类型为
PrintJob*
的数组。我面临的问题是,我尝试使用
delete
删除的第一个元素
arr[0]
奇怪地修改了数组的第二个元素。最后,该元素到达堆的头部,删除它会导致SIGABRT

我最初认为可能是直接从数组中删除它,
delete arr[0]
发出了某种类型的错误,因为我会反复调用
delete arr[0]
;尽管如此,我还是在删除后立即用它的下一个最大的子级更新了
arr[0]
。因此,我尝试将其存储到临时变量中,然后删除它:

void出列(){
PrintJob*temp=arr[0];
////删除arr[0];
滴流(0);
删除临时文件;
}
但我很快意识到我的努力毫无意义。我知道当程序两次尝试删除动态分配的实体时,会发生SIGABRT,但除了第一个元素外,我从未接触过任何其他元素。所以我不明白为什么第二个元素会被垃圾值填充,然后抛出SIGABRT

以下是我使用的一些其他代码:

此函数由上面的函数调用,并控制将当前索引(
n
)的最大子级移动到其位置的过程。它根据需求递归地执行此操作

void trickleUp(int n){
int c=getChild(n,true);//获取较大的子级
如果(c>=MAX\u HEAP\u SIZE){//如果
打印作业*temp=arr[n];
////删除arr[n];
arr[n]=nullptr;
删除临时文件;
返回;
}
arr[n]=arr[c];//更新旧节点
trickleUp(c);//移动到树中的下一个元素;
}
getChild()是前一个函数调用的函数,用于返回当前索引
n
的最大子索引(
ln
:left node,
rn
:right node)

intgetchild(intn,bool g){
int ln=(2*n)+1,rn=(2*n)+2,lp=-1,rp=-1;
if(lngetPriority();
}
if(rngetPriority();
}
返回(!((lp>rp)^g)?项次:rn;
}
我已经多次检查了代码,并且没有看到任何其他逻辑错误,当然,在这个问题得到解决并且能够使用其他示例进行测试之前,我无法真正判断。如果您想自己编译,这里有一个链接,指向所有其他代码。我还附加了一个makefile。

使用一些打印来检测代码会产生以下输出:

set 0
set 1
set 2
set 3
set 4
swap 1, 4
swap 0, 1
copy 1 to 0
copy 4 to 1
delete 4
copy 2 to 0
copy 6 to 2
delete 6
copy 2 to 0
copy 6 to 2
delete 6
copy 2 to 0
copy 6 to 2
delete 6
copy 2 to 0
copy 6 to 2
delete 6
这些数字是进入
arr
的索引。如果我们为这些对象添加一些名称,可能会发现问题出在哪里:

set 0 - A
set 1 - B
set 2 - C
set 3 - D
set 4 - E
swap 1, 4 - 1 == E, 4 == B
swap 0, 1 - 0 == E, 1 == A
copy 1 to 0 0 == A, 1 == A, pointer to E is lost
copy 4 to 1 1 == B, 4 == B
delete 4    delete B, 4 == 0, 1 still points to B
copy 2 to 0 0 == C, 2 == C, pointer to A is lost
copy 6 to 2 2 == 0
delete 6    delete null pointer, has no effect
copy 2 to 0 0 == 0, 2 == 0, pointer to C is lost
copy 6 to 2 2 == 0
delete 6    delete null pointer, has no effect
the rest just further copies around null pointers
在这个特定的示例中,它没有崩溃(至少对我来说),因为没有任何内容被删除两次,但希望它清楚地表明,在不同的数据中,这种情况是如何发生的

大概是:

    arr[n] = arr[c];    // update the old node
应该是:

    arr[c] = arr[n];    // update the old node

这会使您的代码更快崩溃,尽管可能会发现更多的逻辑问题。

请在问题中提供一个无外部链接的链接。
arr[n]=arr[c]
看起来有点可疑,您现在将同一指针存储在两个不同的位置?直到我在下一行
trickleUp(c)
中用其下一个最大的子级更新arr[c]。你仍然建议我修改它吗?你需要调试你的代码,但是当你怀疑double-frees时,你的代码中复制指针的部分可能是一个很好的起点,请发布一篇文章。如果做不到这一点,我可以提供毫无根据的猜测和手工操作。