SIGILL 在 ideone 上运行,但在 Codeblocks 上运行时出现警告
SIGILL on ideone but runs with warning on Codeblocks
我在 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;
}
我在代码块上收到此警告,
/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 上运行完美。
如果您能给我一些见解,我将不胜感激。我试图将 it 放在 scanf 中,因为它是一种指向向量的通用指针。
提前致谢。
scanf
和 printf
是遗留的 C 函数,它们不应与迭代器等 C++ 功能结合使用。具体来说,std::vector<T>::iterator
是实现定义的,可能不仅仅是 T*
,因此您不能依赖对 scanf
的调用是可移植的。
迭代器不一定是指针。因此这段代码会产生未定义的行为:
scanf("%d", it);
您必须给 scanf
一个 int
变量的真实地址。如果您的实现碰巧将 std::vector<int>::iterator
视为指针,那么您将不会看到任何问题。
这个问题有一个真实的例子:
回到 Visual Studio 6.0 流行的时候,很多使用 std::vector
的代码都假设向量迭代器是作为指针实现的,程序员是对的。当时的向量迭代器是作为指针实现的。
然后在 VS 6.0 之后出现 Visual Studio。向量迭代器不再作为简单的指针实现,因此许多遗留代码要么无法编译,要么在偶然编译时被破坏。当您在编写程序时依赖实现细节时会发生这种情况。
我在 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;
}
我在代码块上收到此警告,
/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 上运行完美。
如果您能给我一些见解,我将不胜感激。我试图将 it 放在 scanf 中,因为它是一种指向向量的通用指针。
提前致谢。
scanf
和 printf
是遗留的 C 函数,它们不应与迭代器等 C++ 功能结合使用。具体来说,std::vector<T>::iterator
是实现定义的,可能不仅仅是 T*
,因此您不能依赖对 scanf
的调用是可移植的。
迭代器不一定是指针。因此这段代码会产生未定义的行为:
scanf("%d", it);
您必须给 scanf
一个 int
变量的真实地址。如果您的实现碰巧将 std::vector<int>::iterator
视为指针,那么您将不会看到任何问题。
这个问题有一个真实的例子:
回到 Visual Studio 6.0 流行的时候,很多使用 std::vector
的代码都假设向量迭代器是作为指针实现的,程序员是对的。当时的向量迭代器是作为指针实现的。
然后在 VS 6.0 之后出现 Visual Studio。向量迭代器不再作为简单的指针实现,因此许多遗留代码要么无法编译,要么在偶然编译时被破坏。当您在编写程序时依赖实现细节时会发生这种情况。