XMFLOAT4X4为矩阵定义使用了并集内的并集,但是当我尝试使用相同的方法(有或没有)时,在访问模式中会得到各种各样的结果。我不确定这是在联合的初始化中,还是在实现中可能出错的地方。在我的代码中,单一联合不起作用,但是现在在该代码中,双重联合不起作用。为什么是这样?

#include <stdio.h>

typedef union{
    union{
        struct{float xx,xy,xz,xw, yx,yy,yz,yw, zx,zy,zz,zw, wx,wy,wz,ww;};
        float m[4][4];
    };
}Mat4DoubleUnion;

typedef union{
    struct{float xx,xy,xz,xw, yx,yy,yz,yw, zx,zy,zz,zw, wx,wy,wz,ww;};
    float m[4][4];
}Mat4SingleUnion;

int main(void){
    Mat4SingleUnion mat_single_1 =
    {1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1};
    Mat4SingleUnion mat_single_2 =
    {1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1};
    Mat4DoubleUnion mat_double_1 =
    {1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1};
    Mat4DoubleUnion mat_double_2 =
    {1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1};

    Mat4DoubleUnion out_double;
    Mat4SingleUnion out_single;
    for(unsigned i = 0; i < 4; ++i){
        for(unsigned j = 0; j < 4; ++j){
            out_double.m[i][j] = mat_double_1.m[i][j] + mat_double_2.m[i][j];
            out_single.m[i][j] = mat_single_1.m[i][j] + mat_single_2.m[i][j];
        }
        printf("Double Union\n");
        for(unsigned i = 0; i < 4; ++i){
            printf("[%f  %f  %f  %f]\n", out_double.m[i][0], out_double.m[i][1], out_double.m[i][2], out_double.m[i][3]);
        }
        printf("\n");
        printf("Single Union\n");
        for(unsigned i = 0; i < 4; ++i){
            printf("[%f  %f  %f  %f]\n", out_single.m[i][0], out_single.m[i][1], out_single.m[i][2], out_single.m[i][3]);
        }
        printf("\n");
    }


}


输出如下。您会注意到在整个循环过程中出现的大量数字,到达终点时,这两个矩阵的总和不是正确的输出。

Double Union
[2.000000  0.000000  0.000000  0.000000]
[0.000000  -170141183460469231731687303715884105728.000000  0.000000  0.000000]
[0.000000  0.000000  0.000000  0.000000]
[304728612076653271699817077145600.000000  18030524136642386826155261952.000000  269154975309704986624.000000  73908519441581681410048.000000]

Single Union
[2.000000  0.000000  0.000000  0.000000]
[0.000000  0.000000  0.000000  0.000000]
[0.000000  0.000000  0.000000  0.000000]
[0.000000  0.000000  0.000000  0.000000]

Double Union
[2.000000  0.000000  0.000000  0.000000]
[0.000000  2.000000  0.000000  0.000000]
[0.000000  0.000000  0.000000  0.000000]
[304728612076653271699817077145600.000000  18030524136642386826155261952.000000  269154975309704986624.000000  73908519441581681410048.000000]

Single Union
[2.000000  0.000000  0.000000  0.000000]
[0.000000  2.000000  0.000000  0.000000]
[0.000000  0.000000  0.000000  0.000000]
[0.000000  0.000000  0.000000  0.000000]

Double Union
[2.000000  0.000000  0.000000  0.000000]
[0.000000  2.000000  0.000000  0.000000]
[0.000000  0.000000  2.000000  0.000000]
[304728612076653271699817077145600.000000  18030524136642386826155261952.000000  269154975309704986624.000000  73908519441581681410048.000000]

Single Union
[2.000000  0.000000  0.000000  0.000000]
[0.000000  2.000000  0.000000  0.000000]
[0.000000  0.000000  2.000000  0.000000]
[0.000000  0.000000  0.000000  0.000000]

Double Union
[2.000000  0.000000  0.000000  0.000000]
[0.000000  2.000000  0.000000  0.000000]
[0.000000  0.000000  2.000000  0.000000]
[0.000000  0.000000  0.000000  2.000000]

Single Union
[2.000000  0.000000  0.000000  0.000000]
[0.000000  2.000000  0.000000  0.000000]
[0.000000  0.000000  2.000000  0.000000]
[0.000000  0.000000  0.000000  2.000000]

最佳答案

尝试更改这两行。在启动问题之前,这是非常微妙的用法。

Mat4DoubleUnion out_double; memset(&out_double, 0, sizeof(out_double));
Mat4SingleUnion out_single; memset(&out_single, 0, sizeof(out_single));


在每个外部循环中,您仅初始化out_single和out_double的一行,因此其余行是垃圾。在最后一个外部循环中,所有行均已正确启动,输出正确。我认为未初始化的用途是未定义的行为,所以...

您可以尝试使用内存检查工具valgrind,在这种情况下会告诉很多信息:

valgrind --tool=memcheck ./a.out

07-28 04:30