认为我应该被允许“删除”一个指针,但抛出一个错误“正在使用中的块”

Thinking I should be allowed to `delete` a pointer but an error is thrown `block in use`

考虑这个函数:

bool RemoveElement(const T2& e2)
{
    bool match = false;

    for (int i = 0; i < _trenutno; i++)
    {
        if (*_elementi2[i] == e2){

            match = true;

            for (int j = i; j < _trenutno - 1; j++)
            {
                _elementi1[j] = _elementi1[j + 1];
                _elementi2[j] = _elementi2[j + 1];

                // SOLUTION: The two lines above are not correct.
                // Instead of assigning addresses, I should have assigned
                // values, ie. dereference them like below:

                // *_elementi1[j] = *_elementi1[j + 1];
                // *_elementi2[j] = *_elementi2[j + 1];

            }
        }
    }


    if (match)
    {
        _trenutno--;

        //delete _elementi1[_trenutno];
        _elementi1[_trenutno] = nullptr;

        //delete _elementi2[_trenutno];
        _elementi2[_trenutno] = nullptr;
    }

    return match;
}

仅供参考,指针本身(见下文)。我在上面的函数中尝试使用 delete 删除这对特定指针(最后一个元素)后面的值,否则我相信会发生内存泄漏?

template<class T1, class T2, int max>
class Kolekcija
{
    T1* _elementi1[max];
    T2* _elementi2[max];
    int _trenutno;
public:
    Kolekcija()
    {
        for (int i = 0; i < max; i++)
        {
            _elementi1[i] = nullptr;
            _elementi2[i] = nullptr;
        }
        _trenutno = 0;
    }
    //  ...

    ~Kolekcija()
    {
        for (int i = 0; i < _trenutno; i++){
            delete _elementi1[i]; _elementi1[i] = nullptr;
            delete _elementi2[i]; _elementi2[i] = nullptr;
        }
    }
    // ....

为什么会这样,我想多了解一下,更好地理解指针。

这里你有很多问题,首先你需要删除item,然后为数组中的那个位置设置nullptr值,如果我想像你的情况一样使用T1和T2的数组,那么我会使用矢量而不是简单数组

如果您的 class 是 data owner 并且您想删除一些元素:

  1. 查找元素索引 (_elementi1[nFound] == searchValue)
  2. 从堆中删除这个元素delete _elementi1[nFound];
  3. 将元素的值设置为 nullptr _elementi1[nFound] = nullptr;
  4. 然后才移动尾随元素来代替删除的项目。

此序列将保护您免受 Remove 方法中的内存泄漏。

析构函数将清除其他堆分配的值(假设 _trenutno 是实际的 count):

    for (int i = 0; i < _trenutno; i++)
    {
        delete _elementi1[i]; _elementi1[i] = nullptr;
        delete _elementi2[i]; _elementi2[i] = nullptr;
    }

删除 nullptrsafe

所以我的 Remove() 版本:

bool RemoveElement(const T2& e2)
{
    for (int i = 0; i < _trenutno; i++)
    {
        if (*_elementi2[i] == e2) 
        {
            delete _elementi1[i];
            _elementi1[i] = nullptr;
            delete _elementi2[i];
            _elementi2[i] = nullptr;

            for (int j = i; j < _trenutno - 1; j++)
            {
                _elementi1[j] = _elementi1[j + 1];
                _elementi2[j] = _elementi2[j + 1];
            }
            _trenutno--;
            return true; //found
        }
    }
    return false; //not found
}

我假设您的 collection 是 data owner。所以你 have to delete 所有传递给它的指针。 简单示例(我们添加 3 个值):

int* elements[max] = {0};
elements[0] = new int(4); //0x00FF1F
elements[1] = new int(5); //0x00FF2F
elements[2] = new int(6); //0x00FF3F
_trenutno = 3;

我们必须 delete 全部 3 int*

如果没有 Remove 被调用,析构函数将处理它(从 0 删除到 2)。

如果我们调用Remove(5):

  1. 找到 5 值的索引 i == 1
  2. 调用delete elements[1]表示releaze memory at address 0x00FF2F
  3. 换班:elements[1] = elements[2]

现在我们的数组是:

elements[0]; //0x00FF1F
elements[1]; //0x00FF3F
elements[2]; //0x00FF3F

并且 _trenutno = 2;

因此析构函数将删除从“0”到“1”的指针。

这就是删除的所有 3 个指针!