2013-06-28 211 views
0

從main中,我試圖調用mymath.cpp中的一個主要函數 - 它有一些我不明白的奇怪行爲 。 (注意,該算法不工作 - 但是這不是什麼奇怪的是我。)C++指針 - 奇怪的循環行爲

奇怪的是,如果我註釋掉行:

cout << "n:" << lastPrime->pnum <<"\n"; 

...在mymath.cpp,我的循環在main中只運行兩次。如果我把它放進去,我的主循環一直運行到i = 50;

的main.cpp

#include <iostream> 
#include <stdlib.h> 
#include <time.h> 
#include "stat.h" 
#include "mymath.h"; 

using namespace std; 

int main() 
{ 
    for (int i = 3; i<= 50; i++) 
    { 
     if (isPrime(i)) 
     { 
      cout << i << " is prime!\n"; 
     } 
     else 
     { 
      cout << i << " is NOT prime\n"; 
     } 
    } 

    return 0; 
} 

MYMATH.CPP

#include "mymath.h" 
#include <math.h> 
#include <iostream> 

using namespace std; 

prime two; 
prime * lastPrime = &two; 
prime * firstPrime = &two; 

bool isPrime(long long n) 
{ 
    two.pnum=2; 
    prime * currentPrime = &two; 

    if (n < 2) 
     return false; 

    long long squareRoot = sqrt(n); 

    while(true) 
    { 
     if (n % currentPrime->pnum==0) 
     { 
      //n is divisible by a prime number, nothing left to do. 
      return false; 
     } 
     else 
     { 
      //n is not divisible by a prime... check next one 
      { 
      if (currentPrime->pprime == 0 || currentPrime->pnum > squareRoot) 
       { 
        //this is prime 
        prime addPrime; 
        addPrime.pnum=n; 
        addPrime.pprime=0; 
        lastPrime->pprime=&addPrime; 
        lastPrime=&addPrime; 
        cout << "n:" << lastPrime->pnum <<"\n"; 
        return true; 
       } 
       else 
       { 
        //may not be prime, check next 
        currentPrime = currentPrime->pprime; 
       } 
      } 
     } 
    } 
    return true; 
} 

回答

3

的代碼已經undefined behaviour作爲局部變量,命名爲addPrime,正在使用超出其壽命:

lastPrime->pprime=&addPrime; 
    lastPrime=&addPrime; 
    cout << "n:" << lastPrime->pnum <<"\n"; 
    return true; 
} // 'lastPrime' is now a dangling pointer because it holds the address 
    // of 'addPrime' whose lifetime has ended. 

要更正,您需要使用動態分配prime改爲。 但是,它似乎(沒有定義prime我不確定)代碼是建立一個列表prime s遇到。建議使用std::vector<prime>來建立列表並讓它爲你管理內存。

如果std::vector<prime>是不是一種選擇,無論出於何種原因,然後確保prime所有實例是動態分配的,而不是一個動態分配的情況下和非動態分配的情況下(如全球two)的組合,因爲它是非法的到delete未動態分配的對象。

+0

謝謝 - 我有點理解。動態分配意味着內存不會被重寫,直到我釋放它。本地非動態分配意味着我的內存可能會重寫,即使我有一個指向它的指針? – MathStudent

2

當您添加或刪除無害代碼時,出現和去除的問題幾乎總是由於指針錯誤造成的;有時會覆蓋重要的東西,有時會覆蓋一些無關緊要的東西。

在這種情況下,壞指針來自addPrime的地址並保存。在塊的末尾addPrime消失,並且指向它的指針變得無效。