2017-08-15 33 views
-3

我有一個奇怪的行爲下面的代碼:C++循環掛起,如果任何代碼被添加里面如果條件

struct Mime { 
    int key; 
    string value; 
}; 

class Storage { 

private: 

    int Size; 
    Mime * _storage; 
    int last = 0; 

public: 

    Storage(int __size) { 
     Size = __size; 
     _storage = new Mime[Size + 2]; 
    } 

    void add(const Mime & __mime) { 

     for (int x = 0; x < last; x++) 
      if (_storage[x].key == __mime.key) {} 

     _storage[last++] = __mime; 
    } 
}; 

void test2() { 

    int thisSize = 1000000; 
    Storage storage(thisSize); 
    auto start_t = chrono::high_resolution_clock::now(); 
    for (int i = 0; i < thisSize; i++) { 
     Mime temp; 
     temp.key = i; 
     temp.value = "Hey"; 
     storage.add(temp); 
    } 
    cout << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start_t).count() << " milliseconds\n" << endl; 
} 


int main() { 

    test2(); 

    cout << "Done" << endl; 

    return 0; 
} 

在120毫秒我此代碼運行。但是,當我的{}

if (_storage[x].key == __mime.key) {} 

這裏面添加一些代碼,就像

if (_storage[x].key == __mime.key) { return; } 

或其他任何東西...... 後來我的程序10分鐘跑,有時通過添加return;或任何其他代碼掛起。當我在此if條件中添加return;或任何其他代碼時,我的程序會掛起。在這個(如果)沒有發生在這個過程中,因爲這似乎並沒有運行return;或任何其他代碼。

有什麼建議嗎?

+1

不要在變量名稱前加下劃線。雙下劃線保留給內部的東西 –

+0

行'_storage [last ++] = __mime;'是可疑的。 – Malice

+0

該代碼是真實的...請在您的系統中運行它...這個_storage [last ++] = __mime沒有問題; – MyJustWorking

回答

1

這種行爲沒有什麼奇怪的。它是優化器,它認識到for循環可以安全地在內部沒有空塊的情況下執行。

優化說:

for (int x = 0; x < last; x++) 
    if (_storage[x].key == __mime.key) {} 

看看這個對於有沒有副作用?這意味着,即使執行不改變程序的狀態這一堆線做,所以,我d最好省點時間,不要執行它。

嘗試使用-O0進行編譯,您仍然會得到一個long運行時。


爲了仔細檢查,這是原因之一,可以欺騙編譯器和力使用volatile

所以下面的代碼不會被優化掉,以保持該代碼,而不是不管是什麼for的內容

for (volatile int x = 0; x < last; x++){ 
     //whatever 
    } 
+0

我只是做了一些像地圖一樣的東西,檢查存儲器中是否有這個鍵,不要創建新的鍵(唯一鍵),只是改變這個值,這裏沒有任何相等的鍵,都是新的,所以如果(_storage [x ] .key == __mime.key)從來沒有真正的,這裏沒有問題......但我的問題是,如果我在這種情況下添加一些東西,我的程序掛起,而這從來沒有真正 – MyJustWorking

+1

@MyJustWorking問題不是內容'if'。你試圖做的事情是二次成本,因爲每次添加你用''for'檢查整個數組。所以當你添加第一個元素時,for運行的是'0'迭代,然後是'1'而不是'2',這轉換爲二次的'0 + 1 + 2 + 3..k-1'。這很正常,需要很長時間才能執行。嘗試使用'unordered_set'擺脫那個'for' –

+0

究竟是什麼std :: map做什麼?地圖也需要檢查密鑰(檢查是否存在修改值)不能創建新的! – MyJustWorking