我正在尝试实现一个链表,首先有一个addToFront函数。在这里,我只是将数字 5 添加到列表的前面。我知道如果列表为空,则列表指针应为 Null,但是,情况似乎并非如此。
编辑的文件:我已经编辑了文件(感谢taskinoor的回答(,这些文件现在提供
0 5
而不是
5
我有头文件:
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
typedef struct List {
struct list * next;
int value;
int size;
}list;
void addToFront(int num, list **l);
void printList(list * l);
int getSize(list * l);
void initialize(list * l);
void freeList(list *l);
一个c文件"main.c">
#include "Header.h"
int main() {
list l;
initialize(&l);
addToFront(5, &l);
printList(&l);
_getch();
freeList(&l);
return 0;
}
void printList(list * l) {
list *current = l;
while (current != NULL) {
printf("%d ", current->value);
current = current->next;
}
}
void freeList(list *l) {
list *current = l;
while (current != NULL) {
list *tmp = current;
current = current->next;
free(tmp);
}
}
和一个接口 c 文件(不完整(
#include "Header.h"
int getSize(list * l) {
return l->size;
}
void initialize(list * l) {
l->next = NULL;
l->value = 0;
l->size = 0;
}
// need to pass **l to update it
void addToFront(int num, list **l) {
// allocate memory for new node
list *tmp = (list *)malloc(sizeof(list));
tmp->value = num;
// new node should point to whatever head is currently pointing
// even if head is NULL at beginning
tmp->next = *l;
// finally l needs to point to new node
// thus new node becomes the first node
*l = tmp;
}
但是,当调用 addToFront 函数时,永远不会执行 if 语句。这没有意义,如果列表为空,列表指针不应该为空吗?
接下来,我尝试在Initialize function
中手动设置l == NULL
,但这也没有做任何事情。此外,我的打印函数循环无穷大,我认为这是 malloc 的问题。任何帮助将不胜感激。
条件if (l == NULL)
在addToFront
中不成立,因为l
在这里不为空。您在main
开始时调用了l = malloc(sizeof(list));
,这使l
不为 NULL。无需以这种方式malloc
和初始化l
。我想你所说的l
是指指向列表的头部指针。这在开始时应该是 NULL(即不要在 main
调用 malloc
并将返回的地址分配给 l
(,并且节点的内存应该像这样分配addToFront
:
// need to pass **l to update it
void addToFront(int num, list **l) {
// allocate memory for new node
list *tmp = (list *) malloc(sizeof(list));
tmp->value = num;
// new node should point to whatever head is currently pointing
// even if head is NULL at beginning
tmp->next = *l;
// finally l needs to point to new node
// thus new node becomes the first node
*l = tmp;
}
从main
中删除malloc
。
int main() {
list *l;
addToFront(5, &l); // pass address of l
printList(l);
// other stuffs
}
打印将是这样的:
void printList(list * l) {
list *current = l;
while (current != NULL) {
printf("%d ", current->value);
current = current->next;
}
}
最后,仅释放l
是不够的.您需要遍历整个列表并释放其中的每个节点。
void freeList(list *l) {
list *current = l;
while (current != NULL) {
list *tmp = current;
current = current->next;
free(tmp);
}
}
好的,让我们从最后一部分开始:
我尝试在初始化函数中手动设置 l == NULL,但这也没有做任何事情
实际上它做了一些事情,但是一旦你从初始化函数返回,该更改就会丢失。原因如下:
当你说 initialize(l( 时,在初始化函数体中你会得到原始指针 l 的副本。然后你使该指针指向 NULL。当该函数返回原始指针时,l 仍然指向初始内存(使用 malloc 分配的内存(。如果确实希望此初始化函数具有此类行为,则应将其更改为:
initalize(list **l)
关于 addToFront(( 函数,实际上如果它被执行,你会得到一个段错误!您检查:
if (l == null)
如果是,则尝试取消引用 NULL 指针!
l->value = num;
l->next = NULL;
l->size++;
最后,在打印功能中,您不会推进指针。你应该写一些类似的东西
l=l->next
为了工作
您的打印功能。您只打印后面有下一个节点的值。因此,只有 1 个值不会打印任何内容。相反,您应该拥有:
void printList(list * l) {
while (l !=NULL)
{
printf("%d ", l->value);
l=l->next;
}
}
同样在您的addToFront
函数中,您有一个逻辑错误,如果传入的列表实际上是NULL
,则您只是在设置数据和大小,事实并非如此。
使用:
void addToFront(int num, list **l) {
list *tmp= malloc(sizeof(list));
tmp->value = num;
tmp->next = *l;
*l= tmp;
}
注意:不需要initialize
。只需传递一个空列表或非空列表,这样main
就可以执行以下操作:
int main()
{
list * l= NULL;
addToFront(5, &l);
...
请参阅ForeverStudent他修复打印错误的解决方案。