最近看到一段C语言的代码,引起了我的疑惑。
代码的简单形式如下
typedef unsigned int uint32_t;
typedef struct
{
uint32_t easy;
uint32_t hard;
}mode;
typedef struct
{
uint32_t status;
}type;
int main()
{
type t2 = { 0 };
type* t1 = NULL;
t1 = &t2;
t1->status = 99;
((mode*)&(t1))->easy = 1;
printf("%d", ((mode*)&(t1))->easy);
scanf_s("%d", &((mode*)&(t1))->hard);
printf("%d", ((mode*)&(t1))->hard);
printf("%d", t1->status);
}
但是当我执行上面的代码时,我在最后一个 printf 语句中得到一个错误,作为“访问冲突读取位置 0x00000001”。
如有任何帮助,我们将不胜感激。
最佳答案
这一行在分配给指针的空间中存储了一个int
:
((mode*)&(t1))->easy = 1;
由于 t1
是一个指针,并且您的代码使用一个 & 符号指向它,因此该值不会写入 t2< 的
;它直接写入指针本身的空间。这将解决问题,将 status
字段1
写入 status
字段,这也是 easy
的别名:
((mode*)t1)->easy = 1;
解决了这个问题,下一个问题发生在 scanf_s
行。此行具有未定义的行为,即使您删除了与号:
scanf_s("%d", &((mode*)&(t1))->hard); // <<== Undefined behavior
scanf_s("%d", &((mode*)(t1))->hard); // <<== Also undefined behavior
原始行试图写入超过分配给 t1
指针的位置的堆栈内存,导致从 scanf_s
返回时堆栈损坏。
固定行尝试写入 hard
的位置,该位置超出了 type
结构的末尾。
请注意,将 type*
转换为 mode*
并访问 easy
是可以的:当两个 struct
具有相同的初始成员,您可以自由地将指向一个 struct
的指针转换为另一个 struct
的指针类型。
关于c - C中结构的类型类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23110593/