什么是“部分重叠的对象”?

时间:2011-09-03 11:35:51

标签: c++ object undefined-behavior

我刚刚在this帖子中浏览了所有可能的未定义行为,其中一个是

  

分配给部分重叠的对象的结果

我想知道是否有人能给我一个“部分重叠的对象”的定义,以及代码中如何创建它的例子?

5 个答案:

答案 0 :(得分:4)

正如其他答案所指出的,工会是最明显的安排方式。

这是一个更清晰的例子,说明内置赋值运算符可能会出现部分重叠的对象。如果不是部分重叠的对象限制,则此示例不会显示UB。

union Y {
    int n;
    short s;
};

void test() {
    Y y;
    y.s = 3;     // s is the active member of the union
    y.n = y.s;   // Although it is valid to read .s and then write to .x
                 // changing the active member of the union, .n and .s are
                 // not of the same type and partially overlap
}

即使对于相同类型的对象,您也可能获得潜在的部分重叠。在short严格大于char的情况下,在X未添加填充的实现中,请考虑此示例。

struct X {
    char c;
    short n;
};

union Y {
    X x;
    short s;
};

void test() {
    Y y;
    y.s = 3;     // s is the active member of the union
    y.x.n = y.s; // Although it is valid to read .s and then write to .x
                 // changing the active member of the union, it may be
                 // that .s and .x.n partially overlap, hence UB.
}

答案 1 :(得分:2)

union就是一个很好的例子 您可以使用重叠成员创建内存结构。

例如(来自MSDN):

union DATATYPE    // Declare union type
{
    char   ch;
    int    i;
    long   l;
    float  f;
    double d;
} var1;

现在,如果您使用 char 成员,则所有其他成员都是未定义的。那是因为它们位于相同的内存块中,并且您只为其中的一部分设置了实际值:

DATATYPE blah;
blah.ch = 4;

如果您尝试访问 blah.i blah.d blah.f ,则会有未定义的值。 (因为只有第一个字节,它是一个char,其值已设置)

答案 2 :(得分:1)

这是指指针别名的问题,这在C ++中被禁止,以便为编译器提供更容易的优化时间。可以在this thread

中找到对此问题的详细解释

答案 3 :(得分:0)

可能是指严格的别名规则?内存中的对象不应与其他类型的对象重叠。

  

“严格别名是由C(或C ++)编译器做出的假设,取消引用指向不同类型对象的指针永远不会引用相同的内存位置(即彼此别名。)”

答案 4 :(得分:0)

规范示例使用memcpy:

char *s = malloc(100);
int i;
for(i=0; i != 100;++i) s[i] = i; /* just populate it with some data */
char *t = s + 10;  /* s and t may overlap since s[10+i] = t[i] */
memcpy(t, s, 20); /* if you are copying at least 10 bytes, there is overlap and the behavior is undefined */

memcpy未定义行为的原因是因为没有必要的算法来执行复制。在这种情况下,memmove被引入作为安全的替代方案。