2010-11-01 62 views
4

好,所以这个我真的很困惑。 我正在研究硬件问题,并发现了一些对我来说很奇怪的东西。 这里是有问题指针增加操作员错误

int find_oldest_frame(int **a, int size) 
{ 
    int min = clock(); 
    int **ptr; 
    int *ptr2; 
    int frame = 0; 
    int i; 
    // get address of pointer so we can modify it 
    ptr = a; 
    // store off original pointer location. 
    ptr2 = *a; 

    for (i=0; i<size; i++) 
    { 

     // Who is the oldest time 
     if (**ptr < min) 
     { 
     min = **ptr; 
     frame = i; 
     } 
     printf("Current_Pointer %d\n", *ptr); 
     *ptr++; // For some reason ++ doesn't work. 

    } 
    // now store the oldest frame with the current system time, so it's no longer the oldest. 
    *ptr = ptr2; 
    *ptr += frame; 
    **ptr = clock(); 
    *ptr = ptr2; 
    // Return the array index so that we can change the right page! 
    return frame; 

}

因此,为了使长话短说功能和呼叫,我得到一个弹出式窗口(在Windows中),说有一个问题,必须关闭。当我尝试替换 * ptr ++; 与 * ptr + = 1;

该程序运行。 这让我感兴趣,所以我在GCC 使用-S随着* PTR ++版本我得到这个指令:

addl $4, -20(%ebp) 

与* P + = 1,我得到

movl -20(%ebp), %eax 
movl (%eax), %eax 
leal 4(%eax), %edx 
movl -20(%ebp), %eax 
movl %edx, (%eax) 

这对我看起来像一个非常类似的操作,所以假设我此正确地读取,

壳体1

增量-20(%EBP)4(假定$ 4意味着)

情况下2

我们存储的是在EBP到EAX,

(不知道是什么()做),但再次这样做?

然后采取并加载从EAX 4到EDX偏移地址,

现在复制EBP回EAX再次,

现在复制EDX到EAX,

我的意思是,它看起来像他们'做同样的事情,但由于某种原因* ptr ++!= * ptr + = 1

为什么?我看到的是什么?

编辑:感谢每个人现在我觉得特别,我不能相信我没有意识到这一点!

+0

除非你的asm和我的很不一样(可能是),否则你就是在向后看。 'mov ax,bx' =“将bx复制到ax”。 – egrunin 2010-11-01 14:41:22

+0

@egrunin我不确定它是否全部是相同的,我没有在计算机级读过很多汇编(我已经读过一个关于powerpc的文章,但它不是汇编),所以我有数据交换...对不起:) – onaclov2000 2010-11-01 14:45:25

+1

海湾合作委员会汇编总是在左边的src,dest在右边。 http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html – 2010-11-01 14:46:27

回答

6

这实际上是operator precedence的问题。后缀增量运算符在之前得到应用指针被解除引用,这意味着你增加指针的值(它指向的内存),然后尝试取消引用它。这是调用未定义的行为,因为它指向单个int

在后一种情况下,应用+=发生取消引用,因此您将值存储在指针的内存中,然后添加到它。你需要确保提领先发生,如果你想使用后缀增量,您可以通过做:

(*ptr)++; 

什么,而不是你目前有。

2

*ptr++; // For some reason ++ doesn't work. 

应该

(*ptr)++; 

运算符优先级在此事项 - *ptr++以这种方式工作:*(ptr++) - 相同方式

while((*t++ = *s++) != 0); 

拷贝一个空值终止字符串。

1

++运营商有更高的precedence*,其优先级高于+=++绑定到ptr,而+=绑定到(*ptr)

2

运算符优先级不一样。它们分别相当于:

*(ptr++); 

和:

(*ptr) += 1; 

你可以做*(ptr)++;递增尖值和离开指针本身不变。