[英]How does this work? copying anything into an array of bytes (chars)
struct MyRect
{
int x, y, cx, cy;
char name[100];
};
int main()
{
MyRect mr;
mr.x = 100;
mr.y = 150;
mr.cx = 600;
mr.cy = 50;
strcpy(mr.name, "Rectangle1");
MyRect* ptr;
{
unsigned char bytes[256];
memcpy(bytes, &mr, 256);
ptr = (MyRect*)bytes;
}
printf("X = %d\nY = %d\nCX = %d\nCY = %d\nNAME = %s\n",
ptr->x, ptr->y, ptr->cx, ptr->cy, ptr->name);
return 0;
}
我只是在测试如何将一个struct /类放在一个字节数组中,并且在编译和工作时很惊讶,printf打印出我在mr变量中设置的所有值。
只是有点困惑到什么“ptr”指向? 它在某处为ptr分配了内存吗?
好吧,你的程序会导致未定义的行为,所以你可能不会感到惊讶它恰好工作。 或者,如果它不能正常工作或导致宇宙结束,那么就是这样。 在包含bytes
定义的块之后, ptr
超出范围,并且可能或可能仍未指向有效内存。 在你的情况下,它确实如此。 但你不能依赖这种行为。
unsigned char bytes[256]
在堆栈上分配,即每次输入函数(在本例中为main
)时,堆栈上为变量bytes
保留256 bytes
。 通过cast ptr
现在指向堆栈上的这个区域并解释为MyRect
类型。 由于您首先将此类结构复制到堆栈区域,因此这一切都很好并且有效。 但是一旦你离开main
,区域ptr
指向的区域就消失了,所以你可能不会在这个函数之外存储指向该区域的指针。
ptr
仍指向bytes
地址。 或者,曾经被称为bytes
。 即使你已经将bytes
放入它自己的块中,并且变量在该块之外在语义上是不可访问的,但是在函数退出之前,存储器会保持不变。 这是一种典型的实现技术,但标准未定义,因此不依赖于它。
ptr = (MyRect*)bytes;
“bytes”是内存中数组的地址。
ptr在此代码中分配了该地址。
演员告诉编译器忽略数据类型的差异。
如果你详细了解编译器在幕后做了什么,这当然可以正常工作。 唯一的问题是更改编译器或编译器设置可能会导致此代码失败。 它可能有点脆弱。
它的工作原理是因为虽然'bytes'数组超出了范围,但是当你调用printf()时,它所驻留的堆栈空间还没有被踩到。 它也有效,因为虽然'mr'不是256字节大,但它后面的内存(在堆栈上)并不关心你是在读它。
C是一种非常松散,非类型安全的语言。 指针可以指向任何内存位置,您可以转换为您喜欢的任何指针类型。
所以我同意,你的程序基本上是偶然的。 但它确实如此,因为C允许用指针做一些疯狂的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.