从 'void *' 对 'int' 的赋值使指针从没有强制转换的整数
Posted
技术标签:
【中文标题】从 \'void *\' 对 \'int\' 的赋值使指针从没有强制转换的整数【英文标题】:assignment to 'int' from 'void *' makes integer from pointer without a cast从 'void *' 对 'int' 的赋值使指针从没有强制转换的整数 【发布时间】:2021-02-08 14:55:46 【问题描述】:我正在尝试制作一个链表堆栈,并且我按照在线教程进行操作,但是我收到了这个警告,而作者没有。
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
typedef struct stack
int data;
struct stack *next;
stack;
stack *top;
void Initialize(stack *s)
s=malloc(sizeof(stack));
s->data=NULL;
s->next=NULL;
top=s;
return;
在调试过程中,如果我没有在初始化函数中使用malloc
,则会出现分段错误。
MINGW-W64 编译器。
【问题讨论】:
您似乎遗漏了一些代码。这甚至没有 main,因此我们无法运行此代码来查看您的问题。NULL
通常(但不总是)定义为#define NULL ((void *)0)
,这将导致赋值s->data = NULL;
中出现警告,因为s->data
的类型为int
。也许您应该改用s->data = 0;
。另外,您没有显示函数Initialize
是如何被调用的,但是与参数s
对应的参数被函数忽略了。
要么函数Initialize
有问题,要么函数参数stack *s
没用,应该用局部变量替换。传递给函数的值s
立即被malloc
的结果覆盖。 Initialize
的调用者不会得到修改后的值,因为指针s
是按值传递的。第二个问题:你应该检查malloc
的返回值。如果它返回一个NULL
指针,那么下面对s->data
和s->next
的访问是无效的。
函数参数没有用,因为你将指针分配给全局stack *top;
@Sumsar 可见教程的作者是个低素质的程序员。:)
【参考方案1】:
警告是因为NULL
宏被定义为((void *)0)
(大多数现代编译器),因为它打算仅用于指针。将此值分配给结构的 data
成员会导致警告。
要删除此警告,请使用 s->data=0;
代替 s->data=NULL;
。本教程的作者要么使用了较旧的编译器要么禁用了此特定警告。
此外,传递给您的 Initialize
函数的指针 (s
) 将是您在调用该函数时用作参数的任何变量的 副本,因此,它的值没有在调用代码中更新。您尚未指定您打算如何使用该功能,但这里有一个(也许)更好的实现:
stack* Initialize(void) // Don't need an argument - just return the 'answer'
stack* made = malloc(sizeof(stack));
if (made) // Don't attempt the initialization if "malloc" failed!
made->data = 0;
made->next = NULL;
return made;
然后,当您调用该函数时,您可以将其返回值分配给您的“全局”top
指针:
//...
top = Initialize();
// You should check that 'top' is not NULL before continuing!
【讨论】:
您可以使用类似:stack *test = Initialize ();
,然后在其他检查之前添加 assert(test != NULL)
。【参考方案2】:
在 C 中,宏 NULL 的定义类似于
( void * )0
即表达式的类型是void *
类型的空指针。
因此在此声明中
s->data=NULL;
将指针分配给int
类型的对象,编译器会发出一条消息,指出您做错了什么。
编写的函数 Initialize 没有意义。除此之外,例如这个声明
s=malloc(sizeof(stack));
不会更改用作函数参数的原始指针top
。
其实这个函数是多余的。
不过,如果要写这样一个函数,那么它可能看起来像
stack * Initialize( void )
return NULL;
并像这样称呼
stack *top = Initialize();
或喜欢
void Initialize( stack **top )
*top = NULL;
或者对于一个新创建的节点,它可以像这样声明和定义
void Initialize( stack *s, int data, stack *next )
s->data = data;
s->next = next;
【讨论】:
以上是关于从 'void *' 对 'int' 的赋值使指针从没有强制转换的整数的主要内容,如果未能解决你的问题,请参考以下文章