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

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

本文关键字:一个 错误 使用中的块 允许我 删除 指针      更新时间:2023-10-16

考虑这个函数:

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;
        }
    }
    // ....

为什么会发生这种情况,我想了解更多,更好地理解指针。

如果您的类是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;
    }

删除nullptr即为safe

所以我的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
}

我假设你的收藏品是data owner。所以您have todelete所有传递给它的指针。简单的例子(我们加了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. 找到5i == 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个指针!

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

相关文章: