首页 > 解决方案 > 在 C++ 中应该按什么顺序释放内存?

问题描述

我很难理解delete在 C++ 中使用运算符时应该发生的正确事件顺序。我已经内化了使用它的正确方法是当指针仍在引用指针时。

在下面的示例中 - 我将数组的内容复制到其中temp,然后我也指向delete []了旧数组。arrayPointer

然后我将 指向arrayPointer新创建的数组并将不再需要的设置tempnullptr. 我想通过不删除临时指针来确保不会导致内存泄漏。这还需要发生吗?

nullptr我问是因为我已经看到了我们首先指向的例子,delete但这似乎违反直觉。任何指导将不胜感激。谢谢!

    template <class T>
    void ValSet<T>::add(T elementToAdd){
        if(!this->contains(elementToAdd)){

            if(sizeOfArray == numOfElements){
                sizeOfArray *= 2;
                T* temp = new T[sizeOfArray];
                for (int i = 0; i < numOfElements; i++)
                    temp[i] = arrayPointer[i];
                delete [] arrayPointer;
                arrayPointer = temp;
                temp = nullptr;
            }
        numOfElements += 1;
        arrayPointer[numOfElements-1] = elementToAdd;
        }
      }

标签: c++arrayspointersdynamicdelete-operator

解决方案


As pointed out in the comments to your post, your solution is correct.

In more detail to explain why you're correct, you made sure to allocate more memory before you copied and deleted your current data. That's the only order of things: Reserve (new array), copy, unreserve (old array). (That's how I remember it, anyway.)

In even more detail: temp is a pointer, not the array itself. This is a very crucial and often misunderstood point. I struggled with it a lot, personally. So, when you simply say T* temp;, you are allocating space for a pointer in your current frame. When you say T* temp = new T[size];, you are allocating space for a pointer in your current frame AND asking for more space (equal to sizeof(T) * size Bytes) elsewhere in memory.

This means that temp, as a pointer, is a local variable, but what it points to is not. When you assign arrayPointer = temp;, you are saying your data member points where temp points, but it is not equal to temp in the sense that it is a local variable. This is why you want to delete[] arrayPointer before assigning it to be equal to temp, otherwise you can never reclaim the memory that arrayPointer pointed to. Finally, when you say arrayPointer = temp;, nothing in the memory temp points to is copied over; only the (pointer) value of temp is copied into arrayPointer (hence why you have to explicitly copy the members of the original array into the new array, but not the other way around). Then, when your process exits that frame, all locally declared variables are released, which is why temp goes away as a pointer, but what it pointed to is not released because it was not in the frame (even though it was allocated in the frame).

A couple of pro tips, though: instead of your for-loop, I recommend taking a look at std::copy, and temp = nullptr; is actually superfluous because the memory allocated for temp (as a local variable) will be deallocated once the function returns (as discussed above).

Hopefully that helps a bit conceptually. But, again: you are definitely right :)


推荐阅读