2015-07-21 32 views
1

我正在解決SPOJ上一個簡單的問題,叫做FASHION ...它很簡單。我只想得到迭代器的竅門。但後來我遇到了一個奇怪的問題。SIGILL在ideone上,但在代碼塊上運行時發出警告

這是我的代碼,

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <stdio.h> 

using namespace std; 

int hotMax(vector<int> &, vector<int> &); 

int main() 
{ 
    int iter,m_f; 
    scanf("%d", &iter); 

    vector<int> a,b; 
    while(iter--){ 
     scanf("%d", &m_f); 
     a.resize(m_f); 
     b.resize(m_f); 
     vector<int>::iterator it; 
     for(it = a.begin(); it != a.end(); it++){ 
      scanf("%d", it); 
     } 
     for(it = b.begin(); it != b.end(); it++){ 
      scanf("%d", it); 
     } 
     printf("%d\n", hotMax(a,b)); 
    } 
    return 0; 
} 

int hotMax(vector<int> &a, vector<int> &b){ 
    std::sort(a.begin(), a.end()); 
    std::sort(b.begin(), b.end()); 
    int result = 0; 
    vector<int>::iterator it1,it2; 
    for(it1 = a.begin(),it2 = b.begin(); it1 != a.end(); it1++,it2++){ 
     result+= (*it1) * (*it2); 
    } 
    return result; 
} 

我得到的代碼塊這樣的警告,

 
/home/harshal/c++ tutorial/SAMER08F/main.cpp|22|warning: format ‘%d’ expects argument of type ‘int*’, but argument 2 has type ‘std::vector::iterator {aka __gnu_cxx::__normal_iterator >} 

/home/harshal/c++ tutorial/SAMER08F/main.cpp|25|warning: format ‘%d’ expects argument of type ‘int*’, but argument 2 has type ‘std::vector::iterator {aka __gnu_cxx::__normal_iterator >}’ [-Wformat=]| 

這些對應 scanf("%d", it); 但隨後在代碼塊完美運行,

它在ideone和SPOJ中給出了一個SIGILL。

當我用cin>> *it替換scanf時,它在SPOJ和ideone上運行完美。

如果你能給我一個見解,我將非常感激。我試圖只將放在scanf中,因爲它是一種通用指針,指向矢量。

在此先感謝。

回答

2

scanfprintf是遺留的C函數,它們不應該與迭代器之類的C++函數結合使用。具體來說,std::vector<T>::iterator是實現定義的,可能不僅僅是T*,因此您不能依賴那個可移植的scanf調用。

+0

謝謝,但你能給我提供SIGILL的理由嗎? – harpribot

+2

編譯器可能爲那個'scanf'調用產生一些系統調用,當它碰到實現定義的那個迭代器時,它就會到處噴出。很難說。 – TartanLlama

+0

是否能夠在您的最終重現相同的錯誤?這不好。我知道迭代器不是簡單的'T *',而是'cin >> * it'工作。 – harpribot

1

迭代器是而不是必然是一個指針。因此,該代碼產生不確定的行爲:

scanf("%d", it);

你必須給scanfint變量的一位誠實的地址。如果偶然的實施碰巧考慮了指針std::vector<int>::iterator,那麼您將不會看到任何問題。

有這個問題的一個活生生的例子:

返回時的Visual Studio 6.0是流行的,很多的代碼,用於std::vector假設矢量迭代器被實現爲指針,程序員是正確的。當時的向量迭代器被實現爲一個指針。

然後在VS 6.0之後來到Visual Studio。矢量迭代器不再作爲一個簡單的指針來實現,因此大量的遺留代碼要麼不能編譯,要麼被破壞,如果碰巧他們編譯了。這是在編寫程序時依賴實現細節時發生的情況。

+0

感謝您的解釋 – harpribot

相關問題