值未分配给结构(指针)
Value doesn't assign to struct(Pointers)
当我尝试为 *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)); //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分支,函数必须总是插入新节点。
要以正确的方式实施,需要知道必须在何处进行插入,您的列表是先进先出、后进先出还是根据值对节点进行排序?
假设一个节点总是插在头上:
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
保留 space),所以一旦你尝试写它,段错误。
您有两个选择:
- 用
malloc
为 head
预留 space 就像你对 LinkedList
所做的那样
- 不将
head
声明为指针并将其 space 分配到
stack/global (Node head
).
与 Node *next;
相同,请考虑是否希望指针指向其余代码中已经有效的 Node
。
另一个问题是你没有释放动态内存,不确定你的代码是否只是一个例子,或者你确实有内存泄漏。
您尚未为 list->head
分配内存,这意味着您无法访问或修改 list->head->next
。
您应该首先为列表的头部分配内存:
int main()
{
LinkedList *list = malloc(sizeof(LinkedList)); //Create new linkedlist
list->head = malloc(sizeof(Node)); //Create head
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 );
要检查列表是否为空,你必须至少写 like
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;
}
当我尝试为 *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)); //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分支,函数必须总是插入新节点。
要以正确的方式实施,需要知道必须在何处进行插入,您的列表是先进先出、后进先出还是根据值对节点进行排序?
假设一个节点总是插在头上:
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
保留 space),所以一旦你尝试写它,段错误。
您有两个选择:
- 用
malloc
为head
预留 space 就像你对LinkedList
所做的那样
- 不将
head
声明为指针并将其 space 分配到 stack/global (Node head
).
与 Node *next;
相同,请考虑是否希望指针指向其余代码中已经有效的 Node
。
另一个问题是你没有释放动态内存,不确定你的代码是否只是一个例子,或者你确实有内存泄漏。
您尚未为 list->head
分配内存,这意味着您无法访问或修改 list->head->next
。
您应该首先为列表的头部分配内存:
int main()
{
LinkedList *list = malloc(sizeof(LinkedList)); //Create new linkedlist
list->head = malloc(sizeof(Node)); //Create head
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 );
要检查列表是否为空,你必须至少写 like
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;
}