struct Package_Node
{
int bar_code;
float package_weight;
Package_Node *next_packaged;
};
struct Key_Node
{
int key;
Package_Node *next_package;
};
for(int i=0; i<3; i++)
{
if(keyMain[i].next_package==NULL)
{
continue;
}
if(keyMain[i].next_package!=NULL)
{
nPointer3=keyMain[i].next_package;
nPointer4=keyMain[i].next_package;
while(nPointer3)
{
nPointer4=nPointer4->next_packaged;
delete[] nPointer3;
nPointer3=nPointer4;
}
}
}
keyMain
一个由给定结构key_node
描述的数组。
Key main本身是一个动态数组,但为了代码,我将它显示为一个静态数组。
假设数组长度为3个索引0,1,2
,并且每个索引都包含一个单独的链表。现在我试图删除每个链接列表,但似乎有些被删除而其他人没有删除。
如何解决这个问题?
答案 0 :(得分:1)
你在这里做错了什么?首先,您手动管理内存。
#include <memory>
struct Package_Node
{
int bar_code;
float package_weight;
std::unique_ptr<Package_Node> next_packaged;
};
struct Key_Node
{
int key;
std::unique_ptr<Package_Node> next_package;
};
要在unique_ptr
中存储指针,请使用reset(new Package_Node())
。而不是delete
,请致电reset()
。删除unique_ptr
后,unique_ptr
指向的任何内容都会自动删除。
这是C ++ 11 - 在C ++ 03中,您可能有std::tr1::unique_ptr
或boost::unique_ptr
,但没有移动语义unique_ptr
使用起来更危险。
现在,如果您执行上述操作,您的代码会变得更短,并且取消分配整个链接列表只需.reset()
指向第一个节点的智能指针:其他所有内容都会自动删除!
但是,您可能不愿意这样做。所以我会在你的代码中攻击其他一些问题。
您的变量名称不反映值的用法。 nPointer4
是一个可怕的变量名称。请尝试记录其目的的PointerToDelete
。此外,您应该在初始化点声明指针,并在它无效时清除它,而不是在它使用之前或之后使用它。 (重复使用变量没有获得奖励积分。)
看看这个循环:
nPointer3=keyMain[i].next_package;
nPointer4=keyMain[i].next_package;
while(nPointer3)
{
nPointer4=nPointer4->next_packaged;
delete[] nPointer3;
nPointer3=nPointer4;
}
请注意,nPointer3
和nPointer4
应该在while
的开头保留相同的数据,那么为什么它们都存在?你可以通过这样重写来减半你的状态:
Package_Node* ptrToDelete=keyMain[i].next_package;
while(ptrToDelete)
{
Package_Node* nextPtr = ptrToDelete->next_packaged;
delete ptrToDelete;
ptrToDelete = nextPtr;
}
注意ptrToDelete
仅在初始化时才存在。
注意nextPtr
如何尽可能短的存在,然后超出范围。它只在初始化后才存在。
接下来,总是发布实际演示问题的编译代码。上面的代码不会因为与你的问题完全无关的原因而编译,读你的思想并不是你应该让别人去做的事情。
你不知道出了什么问题,所以你怎么知道什么是重要的?简单:让你的编译器搞清楚。制作一个简单的示例,演示您遇到的问题,编译它,测试问题是否仍然存在,然后发布 。
而不是出现问题,删除部件以缩短部分,发布可能存在或可能不存在问题的非编译代码,并希望其他人可以阅读您的想法。
您完全没有必要使用struct Package_Node*
- Package_Node*
更短,并且(除了一些极端极端情况)完全相同。
即使您不使用智能指针,拥有指针的struct
也应该在其析构函数中销毁它,如果它不拥有指针则应该是其他东西。 RAII是你的朋友。当你拥有一个拥有指针的struct
时,不要忘记关注rule of three。
答案 1 :(得分:1)
我不知道你是如何检查事情是否已被删除;一旦你释放了内存,那个内存就可以被重用了,你不能再被允许访问了 - 虽然没有人会阻止你,除非你造成运行时错误 - 但是内存的内容不会被重新分配修改。 /> 您无法通过检查确定特定对象已被解除分配。
我相信您的问题是,当您完成后,您忘记将keyMain[i].next_package
设置为NULL
。
for(int i = 0; i < 3; i++)
{
if (keyMain[i].next_package != NULL)
{
Package_Node* current = keyMain[i].next_package;
Package_Node* next = 0;
while (current)
{
next = current->next_package;
// No "[]" since you're apparently not allocating with "[]"
delete current;
current = next;
}
keyMain[i].next_package = NULL;
}
}
答案 2 :(得分:1)
由于您在评论中提到nPointer3内存是通过“new Package_Node”分配的,因此行“delete [] nPointer3;”应阅读:
delete nPointer3;
nPointer3 = NULL; // recommended (mentioned in another answer)
您描述的行为可能是由于尝试释放通过singular new分配的nPointer3内存时的未定义行为。只有通过数组new运算符“new []”分配的内存(例如新的Package_Node [16])应该与“delete []”一起发布。