#include <stdio.h>
#include <string.h>
main()
{
int an_int;
void *void_pointer = &an_int;
double *double_ptr = void_pointer;
*double_ptr = 10;
printf("%d", sizeof(*double_ptr));
}
该程序的输出为8.
这是怎么回事?
我的意思是double_ptr指向4字节内存,但仍然输出为8
* 其他4个字节来自哪里???该程序应该崩溃,因为没有分配其他4个字节。 *
请解释一下??
答案 0 :(得分:6)
C是静态类型,表达式sizeof *double_ptr
仅根据这些静态类型规则计算,即double_ptr
指向double
,其大小为8
。
此程序具有未定义的行为,因为您正在写入您不会拥有的内存范围&#34;。所有赌注都已关闭,可能会崩溃或不崩溃。在进行这种讨厌的转换时,你应该对此负责,而不是编译器。
编辑,对于挑剔:
sizeof
运算符的结果不是int
,而size_t
是无符号类型。使用"%d"
进行打印也具有未定义的行为。使用"%zu"
。答案 1 :(得分:2)
我的意思是
double_ptr
指向4字节内存,但仍然输出为8。
这是因为sizeof
是根据表达式的类型或类型进行评估的。此外,在这种情况下,无论指针的值如何,都可以在编译时对其进行全面评估。
*其他4个字节来自哪里???
它们属于与int
位置相邻的内存区域。此区域未分配给您要写入的对象,因此它是未定义的行为。很有可能你正在写入指针本身,如果编译器在void_pointer
之后立即将an_int
放入内存中,就会发生这种情况。
该程序应该崩溃,因为其他4个字节没有分配给它。
不幸的是,并非所有未定义的行为都会导致崩溃。当无效程序没有崩溃时,这是C中的常见情况。例如,所有缓冲区溢出漏洞都依赖于程序在显示未定义的行为后不会崩溃的能力。
答案 2 :(得分:0)
sizeof是编译时运算符。所以它检查指针可能指向的数据类型(两个8字节),因此输出为8.
int main()
{
int an_int;
void *void_pointer = &an_int;
double *double_ptr = void_pointer;
*double_ptr = 10;
printf("%d %d",*double_ptr,sizeof(*double_ptr));
}
我已编辑了一下。它在尝试使用指针访问内存时崩溃。