当我试图找到结构指针的差异时,为什么会出现垃圾值?

时间:2014-08-21 09:19:19

标签: c pointers struct

这是我想要做的事情: -

struct Test
{
    int i;
    char s;
    float f;
};  
int main()
{
    int sizestruct=sizeof(struct Test);
    printf("size of struct=%d\n", sizestruct);
    int maxedge;
    printf("enter maxedge value");
    scanf("%d", &maxedge);
    struct Test *sptr1, *sptr2;
    sptr1=(struct Test *) 1000;
    sptr2=(struct Test *) maxedge;
    printf("sptr1=%d, sptr2=%d\n",sptr1, sptr2);
    printf("then sptr2-sptr1=%d\n", sptr2-sptr1);
    return 0;
}  

现在,如果maxedge = 1996(输出为83),我得到的输出就可以了。即使对于1997,1998和1999年的价值观,它也给出了相同的价值。但对于2000年到2007年的价值,垃圾价值来了。从2008年到2011年的数据,产量为84.但从2012年到2019年,产量仍然是垃圾。

现在考虑这个结构:

struct Test {
    int i;
    char s;
    float f;
    char s1;
};  

对于上面的结构,无论maxedge的值是什么,输出都是正确的。我无法理解为什么上面的代码会出现垃圾值!!

3 个答案:

答案 0 :(得分:6)

我已经尝试过您的代码了。它不会打印垃圾,但乍一看它打印的值与其他值不相关。 (83,-1431655682,1431655849,84)

我不确定它为什么会以这种方式运行,但一般来说,未定义的行为会导致意外行为(就像在这种情况下一样)。

如果指针的差异(以字节为单位)不是12的倍数(一个结构的大小),我们看到的情况可能会发生很奇怪的事情。

除以12明显地以一种除以4然后除以3的方式发生,后者以某种方式执行以便在此处发生。

让我们看一下生成的汇编程序输出:

    movl    28(%esp), %edx
    movl    36(%esp), %eax
    subl    %eax, %edx
    movl    %edx, %eax

这是减法。

    sarl    $2, %eax
    imull   $-1431655765, %eax, %eax
    movl    %eax, 4(%esp)

首先,我们除以4然后用值-1431655765进行乘法运算,这是无符号值2863311531的有符号错误表示。

如果我将此值乘以可分数为3且仅考虑低32位的数字,则将数字除以3.这不适用于其他数字,但可能比分割更快。

所以我们看到,如果不满足某些条件,例如将/ 4'数字的可分性再次提高3,就会发生奇怪的事情。但是没关系,因为没有遵循这些条件是未定义的行为。

答案 1 :(得分:3)

指针差异可能会让你感到惊讶。它会考虑你在数组中要求索引,例如由于array[index]*(array+index)相同,因此在p=&(array[index])然后p - array == index时会自然转变为sizeof(struct Test)

你的结果看起来还是垃圾吗?

那么,也许你可能会考虑比小于{{1}}的偏移,你在索引== i和索引== i + 1之间的某个地方。我怀疑这种行为是在任何地方指定的,所以你可能没想到任何东西。

答案 2 :(得分:1)

减去两个指针同时指向同一个数组元素(或该数组的一个结尾)的指针是未定义的行为。

通常,编译器假定您的代码遵循标准,因此它生成的代码类似于减去地址并除以对象的大小。如果您的代码编译,则工作正常,如果您的代码没有,则可能产生垃圾。