问题描述
当我尝试为*temp
赋值时,它没有赋值(在编译时,它不显示printf,并且按printf看不到任何赋值)。为什么呢我该如何处理有关指针的更多信息(从IDE中查看它们在外部应用程序中所引用的位置??)
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define INT_SIZE sizeof(int) * 8
typedef struct Node Node;
struct Node
{
int value;
Node *next;
};
typedef struct LinkedList
{
Node *head;
}LinkedList;
void Insert(LinkedList **lst,int data)
{
Node *temp = malloc(sizeof(Node));
//Check's if is the first Node.
if ((*lst)->head->next== NULL)
{
(*lst)->head->next = temp;
temp->value = data;
printf("Ok");
temp->next = NULL;
}
}
还有我的主要功能:
int main()
{
LinkedList *list = malloc(sizeof(LinkedList)); //Create new linkedlist
list->head->next = NULL; //Define the head object
Insert(&list,20);
return 0;
}
解决方法
您动态分配了一个列表
LinkedList *list = malloc(sizeof(LinkedList));
,但是其数据成员head
尚未初始化。结果,下一条语句
list->head->next = NULL;
调用未定义的行为,因为使用了变量head
,其值不确定。
没有任何意义将函数Insert
的第一个参数声明为类型LinkedList **lst
,即使用两个间接访问原始列表的类型。最好像这样声明函数
int Insert( LinkedList *list,int data );
要检查列表是否为空,您必须至少像这样写
if ( ( *lst )->head == NULL )
此外,如果列表不为空,则您的函数不执行任何操作。
请注意,通常应检查新节点的分配是否成功。
可以通过以下方式定义功能
int Insert( LinkedList *list,int data )
{
Node *temp = malloc( sizeof( Node ) );
int success = temp != NULL;
if ( success )
{
temp->value = data;
temp->next = list->head;
list->head = temp;
}
return success;
}
无需动态分配列表本身。你可以写
LinkedList list = { .head = NULL };
Insert( &list,20 );
请注意,您需要编写一个释放所有分配的内存的函数。例如
void Delete( LinkedList *list )
{
while ( list->head != NULL )
{
Node *temp = list->head;
list->head = list->head->next;
free( temp );
}
}
这是一个演示程序。
#include <stdio.h>
#include <stdlib.h>
typedef struct Node Node;
struct Node
{
int value;
Node *next;
};
typedef struct LinkedList
{
Node *head;
} LinkedList;
int Insert( LinkedList *list,int data )
{
Node *temp = malloc( sizeof( Node ) );
int success = temp != NULL;
if ( success )
{
temp->value = data;
temp->next = list->head;
list->head = temp;
}
return success;
}
void Delete( LinkedList *list )
{
while ( list->head != NULL )
{
Node *temp = list->head;
list->head = list->head->next;
free( temp );
}
}
void Display( const LinkedList *list )
{
for ( const Node *current = list->head; current != NULL; current = current->next )
{
printf( "%d -> ",current->value );
}
puts( "null" );
}
int main(void)
{
LinkedList list = { .head = NULL };
const int N = 10;
for ( int i = N; i != 0; i-- )
{
Insert( &list,i );
}
Display( &list );
Delete( &list );
return 0;
}
其输出为
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
如果您的编译器不支持指定的初始化,则代替此声明
LinkedList list = { .head = NULL };
您可能只是写
LinkedList list = { NULL };
如果您想在函数Insert
看起来如下时将新节点附加到列表的末尾
int Insert( LinkedList *list,int data )
{
Node *temp = malloc( sizeof( Node ) );
int success = temp != NULL;
if ( success )
{
temp->value = data;
temp->next = NULL;
Node **current = &list->head;
while ( *current ) current = &( *current )->next;
*current = temp;
}
return success;
}
,
您的代码中有很多错误
主要:
LinkedList *list = malloc(sizeof(LinkedList)); //Create new linkedlist list->head->next = NULL; //Define the head object
是错误的,因为list->head
未初始化,因此设置list->head->next
的行为未定义
还有一个逻辑问题,一个空列表为空=>没有节点,正确的初始化为:
list->head = NULL;
插入时:
if ((*lst)->head->next== NULL)
同样,如果由于(*lst)->head
为NULL(在上述更正之后)而导致列表为空时,这是无效的。
也没有 else 分支,该函数必须始终插入新节点。
要以正确的方式实现,需要知道必须在哪里插入,您的列表是fifo,lifo还是根据值对节点进行了排序?
假设始终将一个节点插入头部:
void Insert(LinkedList **lst,int data)
{
Node *temp = malloc(sizeof(*temp));
temp->value = data;
temp->next = (*lst)->head;
(*lst)->head = temp;
}
请注意,使用双指针是没有用的,您可以使用:
void Insert(LinkedList *lst,int data)
{
Node *temp = malloc(sizeof(*temp));
temp->value = data;
temp->next = lst->head;
lst->head = temp;
}
int main()
{
LinkedList *list = malloc(sizeof(*list)); //Create new linkedlist
list->head = NULL;
Insert(list,20);
return 0;
}
最后:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int value;
struct Node *next;
} Node;
typedef struct LinkedList {
Node *head;
} LinkedList;
void Insert(LinkedList *lst,int data)
{
Node *temp = malloc(sizeof(*temp));
temp->value = data;
temp->next = lst->head;
lst->head = temp;
}
void pr(const LinkedList *lst)
{
const Node * l = lst->head;
while (l != NULL) {
printf("%d ",l->value);
l = l->next;
}
putchar('\n');
}
int main()
{
LinkedList *list = malloc(sizeof(*list)); //Create new linkedlist
list->head = NULL;
Insert(list,20);
pr(list);
Insert(list,10);
pr(list);
return 0;
}
编译和执行:
/tmp % gcc -Wall l.c
/tmp % ./a.out
20
10 20
/tmp %
,
您正在尝试使用内存而不分配内存。 LinkedList *
指向有效的(动态分配的)结构,但是head
指向无处(Node
没有保留空间),因此一旦尝试编写它,就会出现段错误。 / p>
您有两个选择:
- 与
malloc
一样,为head
的{{1}}保留空间 - 不将
LinkedList
声明为指针,并在其中分配其空间 堆栈/全局(head
)。
与Node head
相同,请考虑是否要让指针指向其余代码中已经有效的Node *next;
。
另一个问题是您没有释放动态内存,不确定代码是否只是示例还是内存泄漏。
,您尚未为let hours = 2;
let minutes = 3;
let seconds = 20;
function n(n){
return n > 9 ? "" + n: "0" + n;
}
console.log(n(hours) + ':' + n(minutes) + ':' + n(seconds));
分配内存,这意味着您无法访问或修改list->head
。
您应该首先为列表的开头分配内存:
list->head->next