认为我应该被允许`删除'一个指针但是错误被抛出`block in use`

时间:2016-05-11 12:18:32

标签: c++ pointers dynamic-allocation

考虑这个功能:

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

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

2 个答案:

答案 0 :(得分:1)

如果您的班级是data owner,并且您想删除某个元素:

  1. 查找元素(_elementi1[nFound] == searchValue)
  2. 的索引
  3. 从堆delete _elementi1[nFound];
  4. 中删除此元素
  5. 将元素的值设置为nullptr _elementi1[nFound] = nullptr;
  6. 只有移动尾随元素才能代替已移除的项目。
  7. 此序列将保护您免受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
    }
    

    我假设你的收藏是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. 找到5i == 1
    2. 的索引
    3. 致电delete elements[1],即releaze memory at address 0x00FF2F
    4. 转移:elements[1] = elements[2]
    5. 现在我们的数组是:

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

      并且_trenutno = 2;

      因此析构函数会将指针从'0'移除到'1'。

      这是删除所有3个指针!

答案 1 :(得分:0)

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