在ideone上运行SIGILL但在代码块上运行警告

时间:2015-07-21 14:32:19

标签: c++ c++11 vector stl runtime-error

我在SPOJ上解决了一个名为FASHION的简单问题......很简单。我只是想抓住迭代器。但后来我遇到了一个特殊的问题。

这是我的代码,

#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;
}

我在Code-blocks上收到此警告,

/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中放置 it ,因为它是一种指向矢量的通用指针。

提前致谢。

2 个答案:

答案 0 :(得分:2)

scanfprintf是遗留的C函数,它们不应与迭代器等C ++功能结合使用。具体来说,std::vector<T>::iterator是实现定义的,可能不仅仅是T*,因此您无法依赖对scanf的便携式调用。

答案 1 :(得分:1)

迭代器必然是指针。因此,此代码会产生未定义的行为:

scanf("%d", it);

您必须向scanf提供int变量的真实地址。如果您的实施偶然会考虑std::vector<int>::iterator指针,那么您将不会发现任何问题。

这个问题有一个真实的例子:

当Visual Studio 6.0流行时,很多使用std::vector的代码都假定向量迭代器是作为指针实现的,程序员是对的。那时的向量迭代器被实现为指针。

然后是VS 6.0之后的Visual Studio。向量迭代器不再被实现为一个简单的指针,因此许多遗留代码要么不编译,要么在它们编译时偶然被破坏。这就是在编写程序时依赖实现细节时会发生的情况。