简体   繁体   中英

SIGILL on ideone but runs with warning on Codeblocks

I was solving a simple problem on SPOJ called FASHION... its easy. 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,

/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); but then it runs perfectly in codeblocks,

It gives a SIGILL in ideone and also on SPOJ.

When i replace the scanf with cin>> *it , it runs perfectly on SPOJ and 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.

Thanks in advance.

scanf and printf are legacy C functions, they should not be combined with C++ functionality like iterators. 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.

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. If your implementation by chance happens to consider a std::vector<int>::iterator a pointer, then you won't see any issues.

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. The vector iterator at that time was implemented as a pointer.

Then along comes Visual Studio after VS 6.0. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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