无法访问Casted Void指针

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每当我进一步实现链表时都要调用一个新节点.

Iha*_*imi 5

你的代码非常破碎,

  1. 您没有包含任何头文件,至少需要stdlib.hfor malloc()stdio.hfor printf()scanf().

  2. 你的main()定义是错误的,因为main()必须返回int.

  3. fflush(stdin)是未定义的行为.

  4. 您忽略了返回值scanf().

  5. 您假设malloc()始终返回有效指针.

  6. 你调用的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().

  • 这并不明显,这是问题的常见原因.由于您的编译器没有抱怨`readData()`因此认为您没有包含头文件是合理的.隐式函数声明是你的敌人,你似乎忽略了它,因为在调用之前你没有声明`readData()`.如果你没有包含标题,没有启用编译器警告,将使代码编译没有任何问题,这也会发生同样的情况,这并不意味着没有问题. (2认同)