我正在尝试将 Student 类型的元素(定义如下)插入到“NoArv”类型结构(定义如下)的字段“info”中。 我需要通过一个类型为“Base”的指针来执行此操作,它是一个空指针。
我尝试了下面的代码,但是在编译时,我收到了以下错误消息:
> base.c:38:19: error: dereferencing ‘void *’ pointer [-Werror]
>
if(a.ra < (*p)->info.ra)
> ^
> base.c:38:19: error: request for member ‘info’ in something not a structure or union
>
> base.c:39:16: error: dereferencing ‘void *’ pointer [-Werror]
>
*p = (*p)->left;
>
> ^
我怎样才能正确取消引用这样一个指向 void 类型的指针?
我用这个调用函数:InsereBase(&base, student)
其中“base”是Base 类型的变量,“student”是Student 类型的元素。
代码:
Boolean InsertBase(Base *p, Student a) {
while((*p) != NULL){
if(a.ra < (*p)->info.ra)
*p = (*p)->left;
else if(a.ra > (*p)->info.ra)
*p = (*p)->right;
else
return false;
}
*p = MALLOC(sizeof(NoArv));
(*p)->info = MALLOC(sizeof(Student));
(*p)->info.ra = a.ra;
(*p)->info.name = a.name;
(*p)->left = (*p)->right = NULL;
return true;
}
.
typedef void * Base;
typedef char * String;
typedef enum {false, true} Boolean;
.
typedef struct {
int ra;
String name;
} Student;
.
typedef struct AuxNoArv {
Student info;
struct AuxNoArv *left,*right;
} NoArv, * ImplBase;
最佳答案
首先,您将 typedef
d Base
设置为 void *
,因此 Base *< 类型的函数参数
不是 void *
- 它是 void **
。 void *
是通用指针,但 void **
不是,因此您需要修复它。
其次,您必须在取消引用之前强制转换或以其他方式将 void *
转换为适当的类型,如下所示:
#include <stdio.h>
typedef void * Base;
typedef char * String;
typedef struct {
int ra;
String name;
} Student;
void change_student(Base p)
{
Student * s = p;
s->ra = 8;
s->name = "Legs on a spider";
}
void print_student(Base p)
{
Student * s = p;
printf("%d, %s\n", s->ra, s->name);
}
int main(void)
{
Student my_student = {42, "Meaning of life"};
print_student(&my_student);
change_student(&my_student);
print_student(&my_student);
return 0;
}
哪些输出:
paul@horus:~/src/sandbox$ ./void
42, Meaning of life
8, Legs on a spider
paul@horus:~/src/sandbox$
如果您需要指向指针的指针,例如指向 malloc()
节点的一些内存,如您在评论中所建议的那样,则可以是 Student **
转换为 void *
和 Student *
一样好,像这样:
#include <stdio.h>
#include <stdlib.h>
typedef void * Base;
typedef char * String;
typedef struct {
int ra;
String name;
} Student;
void change_student(Base p)
{
Student * s = *((Student **) p);
if ( s ) {
s->ra = 8;
s->name = "Legs on a spider";
}
else {
Student * new_student = malloc(sizeof *new_student);
if ( !new_student ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
new_student->ra = 4;
new_student->name = "Horsemen of the Apocalypse";
*((Student **) p) = new_student;
}
}
void print_student(Base p)
{
Student * s = p;
printf("%d, %s\n", s->ra, s->name);
}
int main(void)
{
Student my_student = {42, "Meaning of life"};
Student * pstudent = &my_student;
print_student(pstudent);
change_student(&pstudent);
print_student(pstudent);
Student * nstudent = NULL;
change_student(&nstudent);
print_student(nstudent);
free(nstudent);
return 0;
}
产量:
paul@horus:~/src/sandbox$ ./void2
42, Meaning of life
8, Legs on a spider
4, Horsemen of the Apocalypse
paul@horus:~/src/sandbox$
关于C:通过空指针引用结构的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26653650/