4 c pointers void void-pointers dereference
我不知道为什么是有必要铸造的void指针,int *或char *打印地址的内容存储器之前,即使我们告诉printf()函数如何解释在内存中的数据?
假设我们有以下代码:
int main (void)
{
void* c = malloc(4);
printf("%d",*c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么不可能这样做?
所以要明确我的问题是这是不可能的原因是什么?
编辑: 在所有的答案和研究之后,我仍然不确定编辑中的致命错误究竟在哪里.我感到困惑的主要原因是我的编译器(gcc)在告诉"取消引用void指针"时只给出一个警告.这是实际的错误吗?据我所知,即使有警告,该程序仍应编译.
EDIT2 我仍然感到困惑的是我们有一个ERROR和WARNING的原因看起来是完全独立的,但是由同一段代码生成:
pointer.c:7:13: warning: dereferencing 'void *' pointer
printf("%d",*p);
^~
pointer.c:7:13: error: invalid use of void expression
printf("%d",*p);
Run Code Online (Sandbox Code Playgroud)
有些用户说只有在我们尝试使用derefenciation的结果时才会出现错误,并且警告是在我们为VOID指针实际分配内存时.
显然不是这种情况,因为如果我们删除printf行,我们确实只会得到一个警告但是完全没有一个警告.
pointer.c:6:8: warning: unused variable 'p' [-Wunused-variable]
void * p=malloc(4);
Run Code Online (Sandbox Code Playgroud)
问题不在于解释printf(),而在于解除引用.
在类似声明的情况下
printf("%d",*c);
Run Code Online (Sandbox Code Playgroud)
你试图取消引用a void *.现在,这void是一个永远不完整的类型.你不能取消引用一个指向"不完整的东西"的指针,并因此得到一些有意义的东西.
引用C11,章节§6.2.5,P19
void类型包含一组空值; 它是一个不完整的对象类型,无法完成.
换句话说(虽然我自己有点),C是一种强类型语言,对于每种定义的类型,编译器知道(或必须知道)它需要读取 /操作的内存中有多少字节(大小)上.对于一个void类型,编译器是无能为力的.
出于同样的原因,void *s 上也不允许使用指针算法.GCC有它的延伸对待一个void*相同的char *,但是这是一个扩展,而不是标准.
编辑:
我的编译器为语句生成错误,在线检查.
*c取消引用指针,它是类型void(不完整类型).您不能取消引用void,因为编译器不知道类型(因此它的大小).因此,取消引用void指针会调用Undefined Behavior.
换句话说,取消引用void指针是不合理的.想象一下你是编译器,你如何插入指针所指向的内存(因为它可以是任何东西)?将a void*转换为正确的类型将起到作用(向编译器提供nessecairy信息).
为什么编译器只发出警告而不是错误?
确实如此,请注意它会生成警告和伴随错误:
main.c:8:14: warning: dereferencing 'void *' pointer
printf("%d",*c);
^~
main.c:8:14: error: invalid use of void expression
printf("%d",*c);
^~~~~~
Run Code Online (Sandbox Code Playgroud)
(gcc)在讲述"取消引用void指针"时给出了一个警告.这是实际的错误吗?
没有.
但是试图使用这种去除反应的结果,你运气不好.
我的意思是:
void* c = malloc(4);
*c;
Run Code Online (Sandbox Code Playgroud)
不会导致错误(但只是一个警告):
main.c:6:2: warning: dereferencing 'void *' pointer
*c;
^~
Run Code Online (Sandbox Code Playgroud)
但是,如果您尝试使用结果*c,则会生成错误.
阅读更多关于理解无效指针的内容.
| 归档时间: |
|
| 查看次数: |
926 次 |
| 最近记录: |