bec*_*kah 1 c pointers linked-list
我正在创建一个链表,其中包含带有void指针的"dataItem"的节点.这样做的目的是为了使Node能够包含任何类型的数据.但是,即使将数据转换为正确的类型,我也无法访问void指针的数据.
我的代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Student
{
char stuName[51];
char stuMajor[5];
double GPA;
char stuID[10];
}student;
typedef struct Node
{
union{
void *dataPtr;
int countr;
}dataItem;
int link;
struct Node* next;
}node;
void readData(struct Node *);
void main(){
node head;
node temp;
readData(&temp);
student *ptr = (student *)(temp.dataItem.dataPtr);
printf("%s %d", ptr->stuName, ptr->GPA);//breaks here because unable to access memory
}
void readData(struct Node *link)
{
link = (node *)malloc(sizeof(node));
student *ptr = (student *)malloc(sizeof(struct Student));
printf("enter the student name : ");
fflush(stdin);
scanf("%[^\n]", ptr->stuName);
printf("enter the student's major : ");
fflush(stdin);
scanf("%[^\n]", ptr->stuMajor);
printf("enter the student GPA : ");
scanf("%lf", &(ptr->GPA));
printf("enter the student ID : ");
fflush(stdin);
scanf("%[^\n]", ptr->stuID);
link->dataItem.dataPtr = ptr;
}
Run Code Online (Sandbox Code Playgroud)
我知道我肯定有一个错误的指针,我不确定如何.我的readData函数中的节点也指向Node的一个新malloc,因为我希望readData每当我进一步实现链表时都要调用一个新节点.
你的代码非常破碎,
您没有包含任何头文件,至少需要stdlib.hfor malloc()和stdio.hfor printf()和scanf().
你的main()定义是错误的,因为main()必须返回int.
你fflush(stdin)是未定义的行为.
您忽略了返回值scanf().
您假设malloc()始终返回有效指针.
你调用的readData()还没有申报.
但是最重要的错误,就是你把node temp地址传递给了readData()你malloc(),但是你并没有返回它的指针,从而失去了所有在里面做出的改变readData(),无论如何它都没有用,因为它在你打电话的那一刻都未被宣布它.
我修改了你的代码,因为我知道你不喜欢我的答案,但查看与答案相关的修复程序,现在它按预期工作
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Student
{
char stuName[51];
char stuMajor[5];
double GPA;
char stuID[10];
} student;
typedef struct Node
{
union{
void *dataPtr;
int countr;
} dataItem;
int link;
struct Node* next;
} node;
void readData(struct Node **link);
int main()
{
node *head;
student *ptr;
readData(&head);
ptr = head->dataItem.dataPtr;
if (ptr != NULL)
printf("%s\t%g", ptr->stuName, ptr->GPA);
return 0;
}
void readData(struct Node **link)
{
student *ptr;
if (link == NULL)
return;
*link = malloc(sizeof(node));
if (*link == NULL)
return;
memset(*link, 0, sizeof(node));
ptr = malloc(sizeof(struct Student));
if (ptr == NULL)
return;
printf("enter the student name : ");
if (scanf("%50[^\n]%*c", ptr->stuName) != 1)
ptr->stuName[0] = '\0';
printf("enter the student's major : ");
if (scanf("%4[^\n]%*c", ptr->stuMajor) != 1)
ptr->stuMajor[0] = '\0';
printf("enter the student GPA : ");
if (scanf("%lf%*c", &(ptr->GPA)) != 1)
ptr->GPA = 0;
printf("enter the student ID : ");
if (scanf("%9[^\n]%*c", ptr->stuID) != 1)
ptr->stuID[0] = 0;
(*link)->dataItem.dataPtr = ptr;
}
Run Code Online (Sandbox Code Playgroud)
我还添加了一些安全修复程序来scanf()添加长度修饰符以防止缓冲区溢出,并且还'\n'使用"%*c"说明符删除尾部,如果多个空格跟随该值,它将无法工作,但是Enter/Return如果您想要更加柔和的输入,您可以同时按下它来测试它,你应该使用别的东西而不是scanf().