C++ SIGILL在ideone上,但在代码块上运行时带有警告
我在SPOJ上解决一个叫做时尚的简单问题。。。这很容易。我只是想掌握迭代器的诀窍。但是我遇到了一个特殊的问题 这是我的密码C++ SIGILL在ideone上,但在代码块上运行时带有警告,c++,c++11,vector,stl,runtime-error,C++,C++11,Vector,Stl,Runtime Error,我在SPOJ上解决一个叫做时尚的简单问题。。。这很容易。我只是想掌握迭代器的诀窍。但是我遇到了一个特殊的问题 这是我的密码 #include <iostream> #include <vector> #include <algorithm> #include <stdio.h> using namespace std; int hotMax(vector<int> &, vector<int> &);
#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;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int hotMax(向量和向量和);
int main()
{
国际热核实验堆;
scanf(“%d”和iter);
载体a,b;
而(国际热核实验堆--){
scanf(“%d”和“m_f”);
a、 调整大小(m_f);
b、 调整大小(m_f);
向量::迭代器;
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));
}
返回0;
}
int hotMax(矢量和a、矢量和b){
排序(a.begin(),a.end());
排序(b.begin(),b.end());
int结果=0;
向量::迭代器it1,it2;
对于(it1=a.begin(),it2=b.begin();it1!=a.end();it1++,it2++){
结果+=(*it1)*(*it2);
}
返回结果;
}
我在代码块上得到这个警告
/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=]|
/home/harshal/c++tutorial/SAMER08F/main.cpp | 22 |警告:格式“%d”要求参数的类型为“int*”,但参数2的类型为“std::vector::iterator{aka uuu gnu_cxx::u normal\u iterator>)
/home/harshal/c++tutorial/SAMER08F/main.cpp | 25 |警告:格式“%d”要求参数的类型为“int*”,但参数2的类型为“std::vector::iterator{aka uu gnu_cxx::u normal_iterator>”[-Wformat=]|
这些都对应于
scanf(“%d”,it)代码>
但它在代码块中运行得很好
它在ideone和SPOJ上给出了一个SIGILL
当我用cin>*替换scanf时,它可以在SPOJ和ideone上完美运行
如果你能给我一个关于这方面的见解,我将不胜感激。我试着把它放到scanf中,因为它是指向向量的广义指针
预先感谢。<> >代码> SCAFF 和 PrTff>代码>是遗留C函数,它们不应该与像迭代器之类的C++功能相结合。具体来说,std::vector::iterator
是实现定义的,可能不仅仅是一个T*
,因此您不能依赖于对scanf
的调用是可移植的。
迭代器不一定是指针。因此,此代码产生未定义的行为:
scanf(“%d”,it)代码>
必须为scanf
变量提供int
的真实地址。如果您的实现意外地考虑了<代码> STD::vector:迭代器< /Cord>指针,那么您将不会看到任何问题。
这个问题有一个真实的例子:
当Visual Studio 6.0流行时,许多使用std::vector
的代码都假设向量迭代器是作为指针实现的,程序员是对的。当时的向量迭代器是作为指针实现的
然后是VS6.0之后的VisualStudio。向量迭代器不再作为一个简单的指针实现,因此许多遗留代码要么无法编译,要么在编译时被破坏。这就是在编写程序时依赖于实现细节时会发生的情况。谢谢,但您能告诉我SIGILL的原因吗?可能编译器会为该scanf
调用生成一些系统调用,当它遇到实现定义为该迭代器的任何东西时,该调用会到处喷涌。但很难说。你能在你这方面重现同样的错误吗?这很糟糕。我知道迭代器不仅仅在T*
中工作,而且在cin>*中工作。Clang为我生成了ud2
指令。感谢您的解释