C 在指针阵列中删除第一个元素,以效应后来的元素



对于实验室分配,我正在处理堆的数组实现。我有一系列PrintJob *类型。我面临的问题是,我尝试使用delete删除的第一个元素arr[0]奇怪地修改了数组的第二个元素。最终,该元素进入了堆的头部,并删除它会导致sigabrt。

我最初是在想直接从数组中删除它,delete arr[0]正在发出某种错误,因为我会反复调用delete arr[0];即使,我在删除它后立即更新arr[0]的下一个最伟大的孩子。因此,我尝试将其存储到临时变量中,然后将其删除:

void dequeue() {
    PrintJob *temp = arr[0];
////    delete arr[0];
    trickleUp(0);
    delete temp;
}

,但我很快意识到我的努力没有任何意义。我知道,当程序尝试删除动态分配的实体时,会发生SIGABRT,但除第一个外,我从不触摸任何其他元素。因此,我很困惑第二个元素为什么填充垃圾值,然后抛出sigabrt。

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

此功能由上面的函数调用,并控制将电流索引(nS(最大的孩子转移到其位置的过程。它按照要求递归地进行。

void trickleUp(int n) {
    int c = getChild(n, true);  // get the greater child
    if (c >= MAX_HEAP_SIZE) {   // if the
        PrintJob *temp = arr[n];
////        delete arr[n];
        arr[n] = nullptr;
        delete temp;
        return;
    }
    arr[n] = arr[c];    // update the old node
    trickleUp(c); // move to the next element in the tree;
}

getChild((是一个函数,该函数由以前的函数调用,该功能旨在返回当前索引n的最大儿童索引(ln:左节点,rn:右节点(。

int getChild(int n, bool g) {
    int ln = (2 * n) + 1, rn = (2 * n) + 2, lp = -1, rp = -1;
    if (ln < MAX_HEAP_SIZE && arr[ln]) {
        lp = arr[ln]->getPriority();
    }
    if (rn < MAX_HEAP_SIZE && arr[rn]) {
        rp = arr[rn]->getPriority();
    }
    return  ( !((lp > rp) ^ g) ? ln:rn );
}

我已经多次检查了代码,但我还没有看到任何其他逻辑错误,当然,在解决此问题之前,我无法真正分辨出来,并且可以使用其他示例进行测试。如果您想自己进行编译,这是指向所有其余代码的链接。我也附上了一个makefile。https://drive.google.com/drive/folders/18idhtro0kuh_aftjgwj3k-4oghbw4h7t?usp = sharing

用某些印刷品仪器会产生以下输出:

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

这会使您的代码崩溃甚至更快,因此可能会发现更多的逻辑问题。

最新更新