繁体   English   中英

通过转换为结构来分配给数组

[英]Assigning to an array by casting to a struct

为什么以下代码有效?

#include <stdio.h>
#define LEN 12

typedef struct
{
    char buffer[LEN];
} string;

int main()
{
    char buffer1[LEN] = "Hello World";
    char buffer2[LEN];

    *(string*)buffer2 = *(string*)buffer1;

    printf("%s",buffer2);
    return 0;
}

据我了解,我不能将一个数组分配给另一个。

C允许将一个结构分配给相同类型的另一个结构,并且这样做的语义是根据结构表示来定义的,而不是逐个成员复制。 结构表示形式包含数组的表示形式并不意味着将包含数组的结构值分配给另一个结构违反了C的禁止将一个数组分配给另一个数组的禁止。

C还保证结构的第一个成员的地址与结构本身的地址相同,并且它允许在不同的指针类型之间强制转换对象指针。 在那种情况下,不能保证这种转换的结果正确对齐,如果不正确,则取消引用该结果会产生不确定的行为。

另一方面,编译器可以自由地在结构表示中包括尾随填充。 通常这样做是为了对齐目的。 如果编译器对结构执行此操作(如果对结构应用64位或更高的对齐要求,则可能执行此操作),则分配会产生未定义的行为。 在这种情况下,如果它看起来可行,那是因为您很幸运。

但是,如果发现以上未定义行为的来源均不适用,那么期望代码按预期工作确实是合理的。 由于很难预测是否会发生这种情况,因此,建议您避免使用这样的代码。

一个更好的问题可能是为什么C不允许数组复制。 可能有多种原因,但我认为最深层的原因只是为了保持一致性。 在几乎所有上下文中,当一个表达式或子表达式对数组求值时,该值将衰减到指向第一个数组元素的指针。 这包括构成=运算符的操作数的子表达式。 因此,在正常的C表达式中,数组分配实际上将是指针分配,而没有预期的语义。 为了允许分配数组,必须为这种情况精心设计适当的特殊情况。

如注释中所指出的,您没有将数组分配给另一个,而是通过强制转换将结构分配给了另一个。 分配结构会导致复制所有元素(如果是简单结构,请参见此文章 )。 但是,代码确实很糟糕,您可以通过在结构中添加另一个字段来破坏它。

根据您的评论“据我所知,我无法将一个数组分配给另一个。” 似乎您创建了该结构,以通过将缓冲区强制转换为该结构来避免无法将一个字符串复制到另一个字符串。

这次碰巧成功了,但它并不总是有效。 结构通常在字段之间具有填充和对齐位。

如果要在C语言中将一个字符串复制到另一个字符串,请使用strcpystrncpy函数(或者,对于wchar_t类型的字符串,请使用wcscpywcsncpy )。

如果要将一个任意类型的数组复制到另一个数组,请使用for循环,在其中逐个复制每个索引或使用memcpy函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM