在c ++中应该以什么顺序释放内存?

时间:2019-05-23 02:08:39

标签: c++ arrays pointers dynamic delete-operator

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

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

然后我将arrayPointer指向新创建的数组,并将不再需要的temp设置为nullptr。我想通过不删除临时指针来确保不会引起内存泄漏。这仍然需要发生吗?

我问,是因为我看过一些示例,我们先指向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;
        }
      }

2 个答案:

答案 0 :(得分:1)

正如您对帖子的评论所指出的那样,您的解决方案是正确的。

要详细说明您的错误原因,请确保在复制和删除当前数据之前分配更多的内存。这是唯一的顺序:保留(新数组),复制,不保留(旧数组)。 (无论如何,这就是我记得的方式。)

更详细地讲:temp是一个指针,而不是数组本身。这是非常关键的,而且常常被误解。我个人为此付出了很多努力。因此,当您简单地说T* temp;时,就是在当前帧中为指针分配空间。当您说T* temp = new T[size];时,您是在当前帧中为指针分配空间,并在内存中的其他位置请求更多空间(等于sizeof(T) * size字节)。

这意味着temp作为指针是局部变量,但它指向的不是。当您分配arrayPointer = temp;时,是在说您的数据成员指向temp指向的位置,但是从它是局部变量的意义上说,它不等于temp。这就是为什么在分配delete[] arrayPointer等于temp之前要arrayPointer,否则您将永远无法回收arrayPointer = temp;指向的内存。最后,当您说temp时,存储器temp中指向的内容均不会被复制;仅将arrayPointer的(指针)值复制到temp中(因此,您必须将原始数组的成员显式复制到新数组中,而不是相反)。然后,当您的进程退出该框架时,将释放所有本地声明的变量,这就是std::copy作为指针消失的原因,但它所指向的内容却未被释放,因为它不在框架中(即使在框架中分配。)

不过,有一些专业提示:建议您不要关注temp = nullptr;,而temp实际上是多余的,因为为def buttoncounter(self): self.showthis = str([self.videofirstbutton.get(), self.videosecondbutton.get(), self.videothirdbutton.get(), self.videofourthbutton.get(), self.videofifthbutton.get(), self.videosixthbutton.get(), self.homevideofirstbutton.get(), self.homevideosecondbutton.get(), self.homevideothirdbutton.get(), self.homevideofourthbutton.get(), self.homevideofifthbutton.get(), self.homevideosixthbutton.get(), self.castingfirstbutton.get(), self.castingsecondbutton.get(), self.castingthirdbutton.get(), self.castingfourthbutton.get(), self.castingfifthbutton.get(), self.castingsixthbutton.get()]) self.counter = print(self.showthis.count('1')) def printbutton(self): self.printbutton = Button(self.frame, text="Print Events " + str(self.counter), width=15, command=self.buttoncounter) #str(self.counter) self.printbutton.pack( side = LEFT ) 分配了内存(函数返回后,将作为一个局部变量)被释放(如上所述)。

希望这会在概念上有所帮助。但是,再次:您绝对是正确的:)

答案 1 :(得分:0)

如果p的值为nullptr,则delete p不执行任何操作。

如果您看到有人将原始指针设置为null然后将其删除的示例,那么这些示例就是错误的代码。

设置指向nullptr的指针不会对其之前指向的基础内存产生任何作用-这是C ++与大多数引用计数或垃圾收集语言之间的关键区别。

另一方面,有许多“智能指针”类在其中实现引用计数语义。 std::shared_ptr是最著名的。因此,也许您看到有人在使用其中之一。对于这些,通常将指针重置为null将减少其引用计数,如果引用计数为1,则将其删除。您不会自己打delete