C++ 为什么使用std::copy()会收到运行时错误(分段错误)?
我在写作业程序 这是关于模拟两个人玩纸牌游戏 起初,Y先生有C++ 为什么使用std::copy()会收到运行时错误(分段错误)?,c++,C++,我在写作业程序 这是关于模拟两个人玩纸牌游戏 起初,Y先生有n卡,而p先生有m卡,并且他们拥有的卡是唯一的 Y先生先玩,下面是你玩游戏的方式: 首先,你选择一个数字x,如果这个数字在你的竞争对手的卡片中,你就接受它 然后,如果你已经有了你得到的牌,你把你手上的牌和你刚得到的牌都扔掉 然后,你的竞争对手做同样的事情(他选择一个数字w) 第一轮比赛到此结束 当其中一个人的牌用完时,游戏结束 此外,如果游戏没有以k回合结束,它将自动结束 程序必须输出: 一个数字l,表示游戏结束的回合数 一轮结束时
n
卡,而p先生有m
卡,并且他们拥有的卡是唯一的
Y先生先玩,下面是你玩游戏的方式:
- 首先,你选择一个数字
,如果这个数字在你的竞争对手的卡片中,你就接受它x
- 然后,如果你已经有了你得到的牌,你把你手上的牌和你刚得到的牌都扔掉
- 然后,你的竞争对手做同样的事情(他选择一个数字
)w
k
回合结束,它将自动结束
程序必须输出:
一个数字l
,表示游戏结束的回合数
一轮结束时Y先生和p先生的牌
我曾尝试使用vector模拟游戏,但当我尝试执行它时,代码出现了分段错误
这是我的密码:
#include<bits/stdc++.h>
using namespace std;
int n,m,k,w,x,a;
vector<int> y,p;
vector<vector<int>> ymoves;
vector<vector<int>> pmoves;
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>a;
y.push_back(a);
}
for(int i=0;i<m;i++){
cin>>a;
y.push_back(a);
}
cin>>k;
bool b=1;
for(int i=0;i<k;i++){
cin>>x>>w;
for(int j=0;j<p.size();j++){
if(p[j]==x){
y.push_back(x);
p.erase(p.begin()+j);
break;
}
}
for(int j=0;j<y.size()-1;j++){
if(y[j]==x){
y.erase(y.begin()+j);
y.pop_back();
break;
}
}
for(int j=0;j<y.size();j++){
if(y[j]==w){
p.push_back(w);
y.erase(y.begin()+j);
break;
}
}
for(int j=0;j<p.size()-1;j++){
if(p[j]==w){
p.erase(p.begin()+j);
p.pop_back();
break;
}
}
copy(y.begin(),y.end(),ymoves[i].begin());
copy(p.begin(),p.end(),pmoves[i].begin());
if(y.empty()||p.empty()){
b=0;
cout<<i<<'\n';
for(int j=0;j<i;j++){
cout<<ymoves[j].size()<<' ';
for(int l=0;l<ymoves[j].size();l++)cout<<ymoves[j].at(l)<<' ';
cout<<'\n';
cout<<pmoves[j].size()<<' ';
for(int l=0;l<pmoves[j].size();l++)cout<<pmoves[j].at(l)<<' ';
cout<<'\n';
}
break;
}
}
if(b){
cout<<k<<'\n';
for(int j=0;j<k;j++){
cout<<ymoves[j].size()<<' ';
for(int l=0;l<ymoves[j].size();l++)cout<<ymoves[j].at(l)<<' ';
cout<<'\n';
cout<<pmoves[j].size()<<' ';
for(int l=0;l<pmoves[j].size();l++)cout<<pmoves[j].at(l)<<' ';
cout<<'\n';
}
}
}
#包括
使用名称空间std;
int n,m,k,w,x,a;
向量y,p;
向量移动;
向量pmoves;
int main(){
cin>>n>>m;
对于(int i=0;i>a;
y、 推回(a);
}
对于(int i=0;i>a;
y、 推回(a);
}
cin>>k;
布尔b=1;
对于(inti=0;i>x>>w;
对于(int j=0;j一个问题,该问题将导致未定义的行为,并且从该点起随时可能导致分段错误,即:
copy(y.begin(), y.end(), ymoves[i].begin());
copy(p.begin(), p.end(), pmoves[i].begin());
ymoves
和pmoves
都以0
的大小初始化。因此,执行ymoves[i]
/pmoves[i]
会导致越界访问,从而导致UB
在全局定义ymoves
和pmoves
时(这在您的情况下没有多大意义,一般应避免),您需要在知道k
有多大时立即使用:
cin>>k;
ymoves.resize(k);
pmoves.resize(k);
但这仍然会导致在执行copy
操作时出现未定义的行为。由于存储在pmoves
/ymoves
中的vecotr
也会初始化为0
大小,但如果使用copy
则必须确保目标足够大以容纳数据
因此,您需要对以下各项执行调整大小:
ymoves[i].resize(y.size());
pmoves[i].resize(p.size());
copy(y.begin(),y.end(),ymoves[i].begin());
copy(p.begin(),p.end(),pmoves[i].begin());
但是我不确定在这里进行复制是否是正确的方法,我也不知道覆盖现有值是否是您想要做的
另外两个错误是:for(int j=0;jIs这是程序中唯一的问题吗?我仍然无法运行它。@Evg调试器可以告诉您segfault发生的确切位置
这是正确的,但segfault发生的位置不一定是导致segfault的位置。如果应用程序能够不要因为之前的UB而处于未定义的状态。帮自己一个忙,给变量起一个有意义的名字来表达它们的用途,阅读和理解只由一个字母组成的代码变量是“可怕的”。这不仅有助于您了解您可能在哪里做错了什么,更重要的是,有人能够理解没有编写它的代码。@Evgymoves
本身已经是空的,因此ymoves[i]
本身已经无效。我发现了导致分段错误的部分,它位于y.erase(y.begin)处()+j);
,p.erase(p.begin()+j);
part.但是为什么呢?@Rachel_Gardner,正如我所说的,由于命名的原因,理解你的代码是不可能的(而且由于你的应用程序现在没有在终端中给出任何预期值的线索,它只是一个等待数据的空控制台,我不得不猜测它是什么).您是否应用了我建议的更改?y.erase(y.begin()+j)
在我看来,这似乎不是SEGFULT的原因,而只是它发生的地方。您需要至少提供一组输入数据,以便重现问题。对于我带来的不便,我深表歉意,以下是代码和输入数据:@Rachel_Gardner我更新了关于您遇到的另一个问题的问题。但这超出了SO的范围。每个问题都应该针对一个问题,而不是进行完整的代码审查。