如果没有malloc,链表实现将失败
linked list implementation fail without malloc
第一个例子是没有动态内存分配的链表。但在这个例子中,当我们运行它时,它只会显示10,然后会提供运行时错误。请帮我找出问题所在。
#include<bits/stdc++.h>
using namespace std;
struct Node{
int data;
struct Node* next;
}Node;
struct Node* head;
void Insert(int x)
{
struct Node* temp;
temp=head;
struct Node* newnode;
newnode->data=x;
newnode->next=NULL;
if(head==NULL)
{
head=newnode;
return;
}
while(temp->next!=NULL)
{
temp=temp->next;
}
temp->next=newnode;
}
void print()
{
struct Node* temp;
temp=head;
while(temp!=NULL)
{
cout<<temp->data<<" ";
temp=temp->next;
}
cout<<endl;
}
int main()
{
head=NULL;
Insert(10);
Insert(20);
Insert(30);
print();
}
在下面的示例中,我刚刚使用malloc为变量提供动态内存。它的工作完全符合预期。为什么两者之间有这样的区别?
#include<bits/stdc++.h>
using namespace std;
struct Node{
int data;
struct Node* next;
}Node;
struct Node* head;
void Insert(int x)
{
struct Node* temp=(struct Node*)malloc(sizeof(struct Node));
temp=head;
struct Node* newnode=(struct Node*)malloc(sizeof(struct Node));
newnode->data=x;
newnode->next=NULL;
cout<<"Reached here"<<endl;
if(head==NULL)
{
head=newnode;
return;
}
while(temp->next!=NULL)
{
temp=temp->next;
}
temp->next=newnode;
}
void print()
{
struct Node* temp=(struct Node*)malloc(sizeof(struct Node));
temp=head;
while(temp!=NULL)
{
cout<<temp->data<<" ";
temp=temp->next;
}
cout<<endl;
}
int main()
{
head=NULL;
Insert(10);
cout<<"Inserted 10"<<endl;
Insert(20);
cout<<"2nd"<<endl;
Insert(30);
cout<<"3rd"<<endl;
print();
}
在没有malloc
的示例中,这只是非法代码:
struct Node* newnode;
newnode->data=x;
newnode->next=NULL;
newnode
是而不是指向任何合法内存,因此使用newnode
写入内存是未定义的行为。
如果您想要一个而不使用的使用malloc
的链表,则必须预先为节点保留内存。例如,您可以在程序启动时创建一个1000个节点的池,然后在程序执行期间使用这些节点。
类似:
static struct node nodePool[1000];
struct node* getNode()
{
// Add code to find an unused node and return a pointer to the node
// This will require some extra data object to track which nodes are free
}
void freeNode(struct node* p)
{
// Add code to mark the node as unused
// This will require some extra data object to track which nodes are free
}
void Insert(int x)
{
...
struct Node* newnode = getNode();
if (newnode == NULL)
{
// No more nodes
add error handling
return something or exit(1);
}
newnode->data=x;
newnode->next=NULL;
...
}
注意:对节点池使用平面阵列是可行的,但对性能不利。Get/fre节点将为O(n(,这对程序性能不利。使用池的程序有更高级的池实现,允许O(1(操作。一种(非常简单(方法是将池控制数据实现为具有头指针和尾指针的链表。这将允许CCD_ 5和CCD_。
注意:我刚刚注意到这个问题同时用C++和C标记。这个答案是用C写的。对于C++代码,没有(也很少有(理由实现自己的链表——只需使用std::list
您的两个示例都是错误的,但原因不同。指针变量需要给定值,就像常规变量一样。因此,您的第一个示例是错误的,因为指针变量newnode
是未初始化的。查看我添加到您的代码中的注释
struct Node* temp; // temp has no value
temp=head; // now temp is given a value
struct Node* newnode; // newnode has no value
newnode->data=x; // ERROR, newnode is used before it's been given a value
newnode->next=NULL;
在给正则变量赋值之前,您不会使用它。指针变量也没什么不同。
第二个例子有相反的错误,您给temp
指针一个值两次!再次查看添加的评论
struct Node* temp=(struct Node*)malloc(sizeof(struct Node)); // temp is given a value
temp=head; // now temp is given a different value,
// the first value is discarded
struct Node* newnode=(struct Node*)malloc(sizeof(struct Node)); // newnode is given a value
newnode->data=x; // newnode is being used correctly
newnode->next=NULL;
您可以通过两种方式给指针一个不同的值,您可以创建一个新节点让它指向,这就是temp=(struct Node*)malloc(sizeof(struct Node));
的作用,或者您可以让它指向一个已经存在的节点,这也是temp=head;
的作用。两者兼而有之没有多大意义。在第二个示例中,使用temp=(struct Node*)malloc(sizeof(struct Node));
创建的节点从未使用过,而是在使temp
指向头节点时创建并丢弃。这被称为内存泄漏。如果泄漏变得足够大,您的程序将耗尽内存。往好里说是浪费。
再想想你将如何使用正则变量,你永远不会写这样的代码int x = 10; x = 20;
——给一个变量一个值,然后在下一行把这个值扔掉,给变量一个不同的值是没有意义的。但这正是您对temp
变量所做的操作。同样,指针并不特殊,适用于正则变量的相同规则也适用于指针变量。
- 如果没有malloc,链表实现将失败
- 单元测试欧拉到四元数实现失败
- CMake + Qt,moc 编译失败,无法实现 QMetaObject 方法(编译器找不到基本 ui 对象的标头?
- 使用双LL在C++中实现Stack失败,出现异常"EXC_BAD_ACCESS(代码=2,地址=0x7fff5
- C++ 链表合并排序的实现在连接 1 个以上节点的子列表时失败
- 有没有一种很好的方法来实现具有默认失败情况的条件类型?
- std::tuple的实现是否允许在触发空类元素的派生到基转换时失败
- 在某些情况下,我的快速排序实现失败
- 使用链接列表实现堆栈,调试断言失败
- 如何在应该失败的CMake中实现编译测试
- WinAPI 如何确保在未实现 WinMain 时编译失败
- 带有实现的纯虚拟函数在XCode中失败
- Boost multiprecision失败是因为complex的实现试图在_Isinf或_Isnan等内部函数中强制转
- cpp -尝试实现触摸功能时断言失败
- 使用Objective-C和C++实现X-FACEBOOK-PLATFORM身份验证失败
- 为什么QueryInterface()会失败,当接口确实在Windows中实现并具有内置编组器时
- Swapcontext在多对多线程实现中失败
- 试图在c++中实现一个堆栈模板(失败得很惨)
- c++多线程优先级实现失败
- 为什么我的简单快速排序实现失败时,等效的元素在数组中