我不确定以下代码的工作原理:
int p = 0;
char* arr = new char[20];
*((int*)&arr[p]) = *((unsigned int*)"ABCD");
以下是我的观察:
arr[p] returns a char
&arr[p] gets the address of the char (char*)
(int*)&arr[p] casts the char* to int*
*((int*)&arr[p]) dereferences the int* to int
"ABCD" is a char*
(unsigned int*)"ABCD" casts the char* to unsigned int*
*(unsigned int*)"ABCD" dereferences the unsigned int* to unsigned int
然后我们复制第一个字符' A' in" ABCD" (将其解释为unsigned int)到arr中的第一个元素(将其解释为int)。然而,通过检查,不仅是arr' A'但第二,第三和第四是' B'' C'和' D'分别
我的问题是,如果我们只复制了第一个字符' A' in" ABCD"对于arr中的第一个元素,其他角色' B'' C'和' D'复制了吗?
谢谢
答案 0 :(得分:4)
你的观察结果是完全正确的,但你似乎错过了对右手方的解除和分配意味着什么。
您没有将char
复制(并转换)为unsigned int
,但您有效地将sizeof(unsigned int)
字节从一个地址复制到另一个地址。
这是一个原因,为什么c样式转换是如此危险(1):你没有将一个字符串转换为unsigned int并分配它,你将一个指针转换为一个char 指针到unsigned int
,然后取消引用它。因此,当解除引用右侧时,编译器只假定从给定地址开始的四个字节(sizeof(unsigned int)
)包含unsigned int
,并且仅从unsigned int
转换为{{ 1}}。
你显然想做的是:
int
但是,请记住 - 正如M.M所指出的那样 - 无论如何左边是UB。
答案 1 :(得分:3)
你写道:
然后我们将“ABCD”中的第一个字符“A”(将其解释为unsigned int)复制到arr中的第一个元素(将其解释为int)。
这个假设是错误的。
由于演员表,// would be better to use our extension method .AsString() which is more performant
var s = myEnum.ToString();
// keepSubscriberReferenceAlive is set to true and returned token is unused, so this is a potential memory leak
eventAggregator.GetEvent<PubSubEvent<IEventHandler>>().Subscribe(EventHandler, ThreadOption.UIThread, true);
复制了*((int*)&arr[p]) = *((unsigned int*)"ABCD");
,其大小为4,因此也会复制B,C和D.
我希望你知道你不会在现实生活中编写这样的代码。