简体   繁体   English

在ideone上运行SIGILL,但在Codeblocks上运行警告

[英]SIGILL on ideone but runs with warning on Codeblocks

I was solving a simple problem on SPOJ called FASHION... its easy. 我在SPOJ上解决了一个名为FASHION的简单问题......很简单。 I just wanted to get hang of iterators. 我只是想抓住迭代器。 But then I am running into a peculiar problem. 但后来我遇到了一个特殊的问题。

This is my code, 这是我的代码,

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

I get this warning on Code-blocks, 我在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=]|

These are corresponding to the scanf("%d", it); 这些对应于scanf("%d", it); but then it runs perfectly in codeblocks, 但它在代码块中完美运行,

It gives a SIGILL in ideone and also on SPOJ. 它在ideone和SPOJ上给出了一个SIGILL。

When i replace the scanf with cin>> *it , it runs perfectly on SPOJ and ideone. 当我用cin>> *it替换scanf cin>> *it ,它在SPOJ和ideone上完美运行。

I shall be very thankful if you could give me an insight on this. 如果你能给我一个洞察力,我将非常感激。 I tried to just place it in the scanf, coz it's kind of a generalized pointer to the vector. 我试图将放在scanf中,因为它是一种指向矢量的通用指针。

Thanks in advance. 提前致谢。

scanf and printf are legacy C functions, they should not be combined with C++ functionality like iterators. scanfprintf是传统的C函数,它们不应与迭代器之类的C ++功能结合使用。 Specifically, std::vector<T>::iterator is implementation defined and may not simply be a T* , so you can not rely on that call to scanf being portable. 具体来说, std::vector<T>::iterator是实现定义的,可能不仅仅是一个T* ,因此你不能依赖于scanf的可移植调用。

An iterator is not necessarily a pointer. 迭代器不一定是一个指针。 Thus this code produces undefined behavior: 因此,此代码产生未定义的行为:

scanf("%d", it);

You must give scanf a bonafide address of an int variable. 你必须给scanf一个int变量的真实地址。 If your implementation by chance happens to consider a std::vector<int>::iterator a pointer, then you won't see any issues. 如果您的实现碰巧考虑使用std::vector<int>::iterator指针,那么您将看不到任何问题。

There is a real life example of this issue: 这个问题有一个真实的例子:

Back when Visual Studio 6.0 was popular, a lot of code that used std::vector assumed that the vector iterator was implemented as a pointer, and the programmers were right. 回到Visual Studio 6.0流行时,很多使用std::vector的代码都假定向量迭代器是作为指针实现的,程序员是对的。 The vector iterator at that time was implemented as a pointer. 当时的向量迭代器被实现为指针。

Then along comes Visual Studio after VS 6.0. 然后是VS 6.0之后的Visual Studio。 The vector iterator was no longer implemented as a simple pointer, thus a lot of legacy code would either not compile, or be broken if by chance they did compile. 向量迭代器不再被实现为一个简单的指针,因此许多遗留代码要么不编译,要么在它们编译时偶然被破坏。 This is what happens when you rely on implementation details when writing your programs. 当您在编写程序时依赖实现细节时会发生这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM