【问题标题】:C++ 2D vector SIGSEV errorC++ 2D 向量 SIGSEGV 错误
【发布时间】:2016-11-11 15:28:43
【问题描述】:

我在以下代码中遇到分段错误,任何人都可以麻烦解释一下。我认为这可能与初始化有关,但不确定。我只是试图克隆现有堆栈并执行操作,例如向克隆添加条目或从现有堆栈中删除条目并将其克隆到新堆栈。

#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <deque>
#include <string>

using namespace std;

#define in cin
#define out cout

int main()
{
    //ifstream in("postfix.in");
    //ofstream out("postfix.out");

    int n;
    in>>n;

    long sum=0;
    vector<int> tm(0);
    vector<vector<int>> ar(0,tm);
    //ar[0].push_back(0);
    out<<ar[0][0];
    for(int i=0;i<n;i++)
    {
        int ind,val;
        in>>ind>>val;
        if(val==0)
        {
            for(int j=0;j<ar[ind-1].size();j++)
            ar[i].push_back(ar[ind-1][j]);
            ar[i].pop_back();
        }
        else
        {
            for(int j=0;j<ar[ind-1].size();j++)
            ar[i].push_back(ar[ind-1][j]);
            ar[i].push_back(val);
        }

    }

    for(int i=0;i<n;i++)
    {
        for(int j=0;j<ar[i].size();j++)
        sum+=ar[i][j];
    }

    out<<sum<<endl;

    return 0;

}

【问题讨论】:

  • 你调试了吗?
  • #define in cin #define out cout -- 请停止这样做。这只会让阅读代码的人更加困惑——每个 C++ 程序员都知道 cincout 是什么,而不会被 #define 宏隐藏。
  • 我正在使用#define 语句,因为我必须先在控制台中对其进行测试,然后才能将其与文件流一起使用,这只是为了方便,我只是将原始代码粘贴在这里,抱歉。
  • @Carcigenicate 我正在使用没有任何调试工具的 gnu g++。
  • @shubhamrock828 你不需要调试器来调试。您可以放置​​打印语句来隔离问题,然后打印出代码的关键部分进行分析。

标签: c++ vector segmentation-fault


【解决方案1】:
vector<int> tm(0);
vector<vector<int>> ar(0,tm);

在这里,您将 ar 初始化为 int 向量的 向量。不通过push_back()resize()insert()等扩大其大小,就无法访​​问ar[i]

您可以改为将ar 初始化为

vector<vector<int>> ar(n);

但是在您提供的现有 sn-p 中,没有关于第二维应该有多大的线索。

根据您在此答案中的评论,您对 tmar 的声明应该是

vector<int> tm(1, 0);
vector<vector<int>> ar(1, tm);

甚至更短,因为tm 以后并没有真正使用,

vector<vector<int>> ar(1, vector<int>(1, 0));

【讨论】:

  • 谢谢 timaru,但我没有把你带到这里。你是什​​么意思初始化空向量?在这里,我试图用 tm 向量在第 0 个索引处初始化数组。 tm 向量也被初始化为 '0' 的一个元素。
【解决方案2】:

我想我知道你在哪里被绊倒了。

vector<int> tm(0);

不会创建一个包含 0 的向量。这会创建一个大小为 0 的向量。因为此列表的大小为 0,所以您无法获取第一个元素;因为它是空的!

这里也一样:

vector<vector<int>> ar(0,tm);

这不会创建具有 1 个“行”的向量。它会创建一个空向量,因为您再次将大小设为 0。

您可能打算这样:

vector<int> tm(1, 0);
vector<vector<int>> ar(1,tm);

这会创建一个带有单个 0 的行 tm,然后创建一个包含该 1 行的二维向量 ar

检查reference。您正在尝试使用“填充”构造函数。

【讨论】:

【解决方案3】:

对于初学者来说,使用这样的定义是个坏主意

#define in cin
#define out cout

最好明确使用std::cinstd::cout,因为任何程序员都知道这些名称的含义。

这些声明

vector<int> tm(0);
vector<vector<int>> ar(0,tm);

意义不大。写起来会更清晰更简单

vector<int> tm;
vector<vector<int>> ar;

因此,由于向量为空,因此您可能不会像在此处那样使用下标运算符

out<<ar[0][0];
     ^^^^^^^^^
for(int i=0;i<n;i++)
{
    int ind,val;
    in>>ind>>val;
    if(val==0)
    {
        for(int j=0;j<ar[ind-1].size();j++)
                    ^^^^^^^^^^^ 
        ar[i].push_back(ar[ind-1][j]);
        ^^^^^
        ar[i].pop_back();
        ^^^^^
    }

等等。在使用下标运算符之前,您首先需要将新元素附加到向量。

【讨论】:

  • 我正在使用#define 语句,因为在将它与文件流一起使用之前我必须在控制台中对其进行测试,这只是为了方便起见,我只是将原始代码粘贴在这里,对此感到抱歉。此外,我正在使用: tm(0) 和 ar(0,tm) 进行初始化,我看不出这里有什么问题。当我 cout 时,为什么我不能在输出中得到 0
  • @shubhamrock828 自从我使用向量以来已经有一段时间了,但是iirc,给构造函数一个数字指定了你想要的大小。您说您希望大小为 0,因此没有要获取向量的第 0 个元素,或者换句话说,您无法获取空向量的第一个元素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-26
  • 1970-01-01
  • 2020-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-01
相关资源
最近更新 更多