我正在编写一个程序,它使用指针和非尖头项的结构,我正在尝试正确地释放我的数据以减少开销(这确实很重要)。
这就是我所拥有的。我本质上是使用特定功能创建自己的队列。我的结构只包含一段通用数据和一个指向下一个位置的指针。
template<class T>
struct Spot
{
T data;
Spot *spotBehind;
};
当我添加新元素时,我会使用以下代码执行此操作(我会跟踪队列的头部和尾部)。
if(front == NULL) //Make first head
{
Spot<T> *newSpot = new Spot<T>();
newSpot->data = newElement;
newSpot->spotBehind = front;
front = newSpot;
back = front;
}
else //Find back of line and add
{
Spot<T> *newSpot = new Spot<T>();
newSpot->data = newElement;
newSpot->spotBehind = NULL;
back->spotBehind = newSpot;
back = newSpot;
}
所以在这之后,当涉及到析构函数时,我当然需要为我拥有的每个 new 都有删除。所以我的析构函数使用代码:
Spot<T> *current = front;
Spot<T> *next = NULL;
while(current != NULL)
{
next = current->spotBehind;
delete current;
current = NULL;
current = next;
}
现在我关注的是这里。当我使用我的析构函数时,我不认为它正在做它应该做的事情,我可能在这里有内存泄漏。通过各种 cout 语句,我可以验证我的信息是否存储并按预期工作。但是当我删除数据时,它实际上似乎没有被删除。为了尝试调试它,我用以下内容替换了重构器代码(上面)以了解它正在做什么。
while(current != NULL)
{
next = current->spotBehind;
cout << "Before Delete " << current << " Data: " << current->data << endl;
delete current;
cout << "After Delete " << current << " Data: " << current->data << endl;
current = NULL;
cout << "After Null " << current << endl;
current = next;
if(current != NULL)
cout << "After Reassigned " << current << " Data: " << current->data << endl;
}
我得到以下结果:
Before Delete 0x100103b20 Data: 5
After Delete 0x100103b20 Data: 5
After Null 0x0
After Reassigned 0x100103b30 Data: 10
Before Delete 0x100103b30 Data: 10
After Delete 0x100103b30 Data: 10
After Null 0x0
所以我的重要问题是,信息实际上是按照预期的方式解除分配的。我在想我做错了什么,因为在我的Spot指针上使用'delete'命令之后,我仍然可以看到值(以及spotBehind指针)。如果它按我想要的方式工作,我不应该看到垃圾值和一个空的spotBehind指针或者只是无法访问数据?我很感激有人向我解释这个问题,如果我这样做不正确,有人会建议一种正确删除信息的方法吗?
答案 0 :(得分:2)
我认为您的代码按预期工作。
删除正常后数据仍然存在,因为删除并不意味着必须覆盖它。 delete只告诉内存管理指针指向的内存不再被使用,可以重新分配。在该操作之后访问它是非法的并且可能导致未定义的行为,但大多数情况下可能没有任何访问冲突,因为该地址仍然指向应用程序堆。
答案 1 :(得分:2)
内存分配通常使用某种链表实现。自由操作标记块可用于系统。 通常,释放内存将取决于编译器和构建类型 - 您是否在Debug of Release中打印了这些值?
例如,调试模式下的MS编译器通过
填充释放的块memset(pHead, _bDeadLandFill, // 0xdddddddd
此处0xdddddddd
是编译器用于标记freed memory的特殊值。
尝试打印已删除指针的数据会导致Access violation
错误。
您可以尝试调试operator delete
以查看它在系统中的实现方式。