在Intel X_86和ARM体系结构上转储两个相邻的C阵列时会出现奇怪的不同结果

在Intel X_86和ARM体系结构上转储两个相邻的C阵列时会出现奇怪的不同结果,c,arrays,raspberry-pi,arm,C,Arrays,Raspberry Pi,Arm,在两种不同的计算机体系结构中,使用C转储相同的两个数组时,我得到了两个不同的结果。谁能给我解释一下原因吗 架构一:x86_64(带fedora 23的普通64位intel PC) 架构二:armv7l(带树莓的树莓pi) 下面是代码示例 double ytops[7]; double ybots[7]; // Assigning values loop for(int i=0;i<8;i++) { frame_grabber(); //

在两种不同的计算机体系结构中,使用C转储相同的两个数组时,我得到了两个不同的结果。谁能给我解释一下原因吗

  • 架构一:x86_64(带fedora 23的普通64位intel PC)

  • 架构二:armv7l(带树莓的树莓pi)

  • 下面是代码示例

    double ytops[7];
    double ybots[7];                     
    
    // Assigning values loop
    for(int i=0;i<8;i++)
    {
        frame_grabber(); // some custom function that gives sensor data with two variables: ruler_top_cal_preset, ruler_bottom_cal_preset integer
    
        ytops[i] = ruler_top_cal_preset;
        ybots[i] = ruler_bottom_cal_preset;
    
        printf("ytops[%i]: %f \n", i, ytops[i]);
        printf("ybots[%i]: %f \n", i, ybots[i]);
    }
    
    printf("---raw-array--- \n");
    
    for(int i = 0; i<8; i++ ){ 
         printf("ytops[%i]: %f \n", i, ytops[i]);
    }
    
    printf("--------------- \n");
    
    for(int i = 0; i<8; i++ ){ 
         printf("ybots[%i]: %f \n", i, ybots[i]);
    }
    
    printf("-------end----- \n");
    
    体系结构2(ARMV7l)给出了以下信息:

    ytops[0]: 143.000000 
    ybots[0]: 211.000000 
    ytops[1]: 143.000000 
    ybots[1]: 211.000000 
    ytops[2]: 143.000000 
    ybots[2]: 175.000000 
    ytops[3]: 144.000000 
    ybots[3]: 175.000000 
    ytops[4]: 144.000000 
    ybots[4]: 175.000000 
    ytops[5]: 144.000000 
    ybots[5]: 175.000000 
    ytops[6]: 144.000000 
    ybots[6]: 172.000000 
    ytops[7]: 143.000000 
    ybots[7]: 172.000000 
    ---raw-array--- 
    ytops[0]: 143.000000 
    ytops[1]: 143.000000 
    ytops[2]: 143.000000 
    ytops[3]: 144.000000 
    ytops[4]: 144.000000 
    ytops[5]: 144.000000 
    ytops[6]: 144.000000 
    ytops[7]: 143.000000 
    --------------- 
    ybots[0]: 211.000000 
    ybots[1]: 211.000000 
    ybots[2]: 175.000000 
    ybots[3]: 175.000000 
    ybots[4]: 175.000000 
    ybots[5]: 175.000000 
    ybots[6]: 172.000000 
    ybots[7]: 172.000000 
    -------end----- 
    
    ytops[0]: 206.000000
    ybots[0]: 413.000000
    ytops[1]: 206.000000
    ybots[1]: 411.000000
    ytops[2]: 205.000000
    ybots[2]: 427.000000
    ytops[3]: 206.000000
    ybots[3]: 415.000000
    ytops[4]: 205.000000
    ybots[4]: 416.000000
    ytops[5]: 205.000000
    ybots[5]: 421.000000
    ytops[6]: 206.000000
    ybots[6]: 411.000000
    ytops[7]: 206.000000
    ybots[7]: 418.000000
    ---raw-array---
    ytops[0]: 418.000000
    ytops[1]: 206.000000
    ytops[2]: 205.000000
    ytops[3]: 206.000000
    ytops[4]: 205.000000
    ytops[5]: 205.000000
    ytops[6]: 206.000000
    ytops[7]: 206.000000
    ---------------
    ybots[0]: 413.000000
    ybots[1]: 411.000000
    ybots[2]: 427.000000
    ybots[3]: 415.000000
    ybots[4]: 416.000000
    ybots[5]: 421.000000
    ybots[6]: 411.000000
    ybots[7]: 418.000000
    -------end-----
    
    当然,在比较两个结果集时,数值是不同的,这是由于当时的传感器数据。可以接受

    在架构1上,所有内容都是由赋值循环赋值的。这是正确的。然而,看看架构2的结果集“值分配循环”中的“ytops[0]”值和“raw array”打印的相同值

    ytops[0]
    正在获取
    ybots[7]


    这怎么可能?这种现象叫什么?如何避免这种情况?

    你所有的理由都是错误的

    使用数组索引从数组-1的
    0
    length\u开始

    所以,使用

    for(int i=0;i<8;i++)
    
    最好是这样做,例如使用
    ytops
    array

    for(size_t i=0;i<sizeof(ytops)/sizeof(ytops[0]);i++)
    

    用于(size_t i=0;ienable
    -Wall
    并在编译时阅读警告您将其标记为
    C++
    ,但如果您实际使用了
    C++
    ,@PaulMcKenzie Yeah。我删除了标记并感谢您提供的信息。请解释否决票?它在英特尔PC上运行时是否有任何特别的原因?@inckka由于内存对齐我我猜是nt。试着打印两个数组的地址,看看第一个数组的最后一个元素和第二个数组的第一个元素之间是否有超过1个
    double
    。@inckka行为未定义,意味着任何事情都可能发生。询问它为什么“有效”是毫无意义的,因为“有效”如果行为是未定义的,就会发生这种情况。@PaulMcKenzie我完全同意,但我认为这是一个很好的练习,可以理解特定的未定义行为为什么以及如何在特定的配置中具有确定性。它将概念刻在内存中。@LPs:但这种未定义的行为取决于特定版本的编译编译器知道
    ybots
    ytops
    不重叠,可以自由地对内存写入进行重新排序,也可以在刷新到内存之前打印寄存器中包含的值(知道内存区域不能被任何其他指令更改)。Oops,如果您调用UB,上述内容不适用,但编译器可以自由给出任何结果。
    for(size_t i=0;i<sizeof(ytops)/sizeof(ytops[0]);i++)