C++ 为什么使用std::copy()会收到运行时错误(分段错误)?

C++ 为什么使用std::copy()会收到运行时错误(分段错误)?,c++,C++,我在写作业程序 这是关于模拟两个人玩纸牌游戏 起初,Y先生有n卡,而p先生有m卡,并且他们拥有的卡是唯一的 Y先生先玩,下面是你玩游戏的方式: 首先,你选择一个数字x,如果这个数字在你的竞争对手的卡片中,你就接受它 然后,如果你已经有了你得到的牌,你把你手上的牌和你刚得到的牌都扔掉 然后,你的竞争对手做同样的事情(他选择一个数字w) 第一轮比赛到此结束 当其中一个人的牌用完时,游戏结束 此外,如果游戏没有以k回合结束,它将自动结束 程序必须输出: 一个数字l,表示游戏结束的回合数 一轮结束时

我在写作业程序

这是关于模拟两个人玩纸牌游戏

起初,Y先生有
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而处于未定义的状态。帮自己一个忙,给变量起一个有意义的名字来表达它们的用途,阅读和理解只由一个字母组成的代码变量是“可怕的”。这不仅有助于您了解您可能在哪里做错了什么,更重要的是,有人能够理解没有编写它的代码。@Evg
ymoves
本身已经是空的,因此
ymoves[i]
本身已经无效。我发现了导致分段错误的部分,它位于
y.erase(y.begin)处()+j);
p.erase(p.begin()+j);
part.但是为什么呢?@Rachel_Gardner,正如我所说的,由于命名的原因,理解你的代码是不可能的(而且由于你的应用程序现在没有在终端中给出任何预期值的线索,它只是一个等待数据的空控制台,我不得不猜测它是什么).您是否应用了我建议的更改?
y.erase(y.begin()+j)
在我看来,这似乎不是SEGFULT的原因,而只是它发生的地方。您需要至少提供一组输入数据,以便重现问题。对于我带来的不便,我深表歉意,以下是代码和输入数据:@Rachel_Gardner我更新了关于您遇到的另一个问题的问题。但这超出了SO的范围。每个问题都应该针对一个问题,而不是进行完整的代码审查。