2010-11-01 44 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)++;遞增尖值和離開指針本身不變。