我很难理解在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;
}
}
答案 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
。