如何解决循环单链接列表中的内存释放
我目前正在刷新有关数据结构的知识。今天,我决定看一下链接列表。我已经完成了单链表和双链表的基本概念。但是,在C语言中实现循环单链表时遇到了一个小问题。
在创建具有3个节点的循环单链列表并打印其层次结构之后,我想重新分配节点的内存。但是,每当我尝试运行代码时,都会引发异常。据我了解,问题与行free(one);
有关。如您在我的代码中看到的,我什至试图预先断开节点之间的链接。这个问题背后的原因是什么,是否是因为我以错误的方式释放了循环链表中的内存?如果不是,应该采取什么方法摆脱这个问题?
#include <stdio.h>
#include <stdlib.h>
typedef struct NodeSL nodeSL;
struct NodeSL{
int data;
nodeSL *next;
};
void circularLinkedList();
int main(){
/* Circular Link List Example */
circularLinkedList();
return 0;
}
void circularLinkedList(){
/* Initializing the nodes. */
nodeSL *head,*one,*two,*three;
/* Allocating the memory. */
one=(nodeSL*)malloc(sizeof(nodeSL));
two=(nodeSL*)malloc(sizeof(nodeSL));
three=(nodeSL*)malloc(sizeof(nodeSL));
/* Assigning data values. */
one->data=1;
two->data=2;
three->data=3;
/* Connecting the nodes. */
one->next=two;
two->next=three;
three->next=one;
/* Saving the address of the first node in head. */
head=one;
nodeSL *p;
int flag=1;
p=(nodeSL*)malloc(sizeof(nodeSL));
p=head;
printf("THIS IS AN EXAMPLE OF A CIRCULAR LINKED LIST!\n");
printf("Head has the address %u\n",head);
while (flag) {
printf("Data: %d",p->data);
printf("\tAdress: %u",p);
printf("\tPoints Forward to the Address: %u\n",p->next);
p=p->next;
if(p==one)
{
flag=0;
}
}
printf("\n\n");
/* Deallocating the memory. */
three->next=NULL;
two->next=NULL;
one->next=NULL;
head=NULL;
free(p);
free(two);
free(three);
free(one);
}
解决方法
您将head
设置为等于one
。然后,将p
设置为等于head
,因此将p
设置为等于one
。然后,您free(p)
,也free(one)
。因此,您可以释放已经释放的已分配块。
此外,这段代码是令人迷惑的:
p=(nodeSL*)malloc(sizeof(nodeSL));
p=head;
为什么要分配一个新节点,然后将p
更改为指向head
并泄漏刚刚无意义分配的节点?您是要p
指向head
已经指向的节点,还是要p
指向新分配的节点?下定决心。
这里可能有两个错误。
-
p
是head
,而head
是one
,释放p
和one
意味着将指针分配两次。
/* Saving the address of the first node in head. */
head=one;
- 通过分配内存泄漏并立即再次分配给内存。
p=(nodeSL*)malloc(sizeof(nodeSL));
p=head; // p is leaked.
我想您实际上是想要p->next = head
。
您将陷入一些初学者在使用指针时遇到的经典陷阱。
public Cell(int x,int y) {
super(x,y,size,size);
random_int = (int) (Math.random() * (maxyellow - minyellow + 1) + minyellow);
}
void paint(Graphics g,Point mousePos) {
if (contains(mousePos)) {
g.setColor(Color.GRAY);
}
else {
g.setColor(Color.getHSBColor(255,random_int,60));
}
g.fillRect(x,size);
g.setColor(Color.BLACK);
g.drawRect(x,size);
}
您忘记了指针只是引用某个内存位置的数字。如果要使用指针(在这种情况下为nodeSL *p;
p = malloc(sizeof(nodeSL));
p = head;
// ...
free(p)
)来遍历列表,则无需从系统请求内存。
简而言之,这里拥有的是双重自由。您释放了p
,然后释放了p
,这与循环后one
的值相同。如果使用调试器,则会在此行看到错误。
此外,您已分配内存,将其存储在p
中,并通过在p
中存储其他值立即泄漏该内存。
所以,只要不这样做,就可以了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。