【问题标题】:C++ Segmentation Fault when attempting to write to a vector passed by reference [closed]尝试写入通过引用传递的向量时出现 C++ 分段错误 [关闭]
【发布时间】:2014-08-22 16:30:57
【问题描述】:

我在这个程序上度过了一段艰难的时光,我超级生疏,而且似乎从来没有学到很多我应该掌握的关于指针、内存管理和一般编程的东西。

我正在尝试制作一个在多个函数中使用相同结构的二维向量的程序。为此,我通过引用初始化函数来传递这个向量,该函数将填充向量中的结构。如果这种方法有什么问题,我很想听听任何更好的建议。

在任何情况下,当我为填充数据而设置的循环尝试写入结构时,我会立即收到段错误。我确信我正在尝试写一种奇怪的记忆艺术,但我对 C++ 中的内存使用的理解似乎比我想象的要少。

我已经在网上和 StackOverflow 上四处寻找,并尝试实施我发现无济于事的解决方案。我有一种非常强烈的感觉,我忽略了一些非常微不足道的事情,当我发现我是一个愚蠢的人时,我会感到非常羞怯(就像我对上一个问题所做的那样)。然而,我非常沮丧,想弄清楚这一点,我呼吁你们这些了不起的人。

感谢您花时间阅读所有这些,只是想尝试彻底。

这是有问题的代码,对任何古怪的格式表示歉意,我是该网站的新手:

结构如下:

struct entry {
    int eTime;
    string eType;
    int pid;
};

这是我遇到问题的功能:

void init(vector< vector<entry> > & pVect, vector< vector<entry> > & eVect){

entry newProcess;                      //to be added to the Process List
entry newEvent;                        //to be added to the Event List

int processNum;                        //For tracking number of processes in ProcessList
int eventNum;                //For tracking number of processes in Process List
string eTy;
int eTi;

cout << "Enter the command, then the number of cycles to be reserved for it." << endl;
cout << "Processing Input...";

int pid = -1;
int i = 0;
    while(cin >> eTy){
        cin >> eTi;

        if(eTy == "NEW"){
            cout << endl;
            pid++;
            cout << "DB: Process " << pid << ":" << endl;
            processNum = pid;

        newEvent.eType = "ARRIVAL";
        newEvent.eTime = 0;
        i = 0;
        }
        else{
            pVect.resize(10);
            pVect.at(pid).at(i).eType = eTy;
            pVect.at(pid).at(i).eTime = eTi;
            pVect.at(pid).at(i).pid = pid;

            cout << "Type: " << pVect[pid][i].eType << " | ";

            cout << "Time: " << pVect[pid][i].eTime << endl;

            i++;
        }
    }
  }

不管它的价值,这是主要功能:

int main(){


  int cpu = 2;

  vector< vector<entry> > processVector(10);
  vector< vector<entry> > eventVector(10);

  int processNum;
  int eventNum;

    init(processVector, eventVector);

    cout << endl << endl;


cout << "Process Vector - Original Order:" << endl;

//And then I'm going to output the actual process vector here, to make sure I've got the right idea.

 }

设置了输入循环,以便我可以手动测试条目或将 STDIN 重定向到输入文件。输入是一个字符串,后跟一个整数。示例输入如下所示:

[input.txt]
NEW   5
CPU   100
INPUT 5000
CPU   80
SSD   1
CPU   30
NEW  100
CPU  20
SSD   0 
CPU   20

【问题讨论】:

  • 有许多输入会导致此崩溃,但如果没有示例输入,则很难判断 预期 输入是什么。如果您提供示例 有效 输入,它会更容易为您提供帮助。
  • 您的 processVector 和 eventVector 对象没有被赋予任何初始大小,也没有调整大小,也没有在您开始索引之前将任何数据推入它们......当然它们会崩溃。您应该找到有关矢量使用的简短教程。另外,vector&lt; vector&lt;entry&gt; &gt; procList = pVect; 会复制(空)输入向量,因此即使您正确地将push_back 值放入其中,原始向量也不会更新,并且procList 会在init 函数返回时消失:要么procList 引用或删除它并直接更新pVect
  • Merlin2011 - 谢谢,我会相应地更新问题。
  • 谢谢,Tony D,我也会调查一下。我以为这很简单。
  • 另外,在再次查看您的评论时,Tony D,我确实需要摆脱 procList。感谢您接听!

标签: c++ vector segmentation-fault pass-by-reference


【解决方案1】:

当你这样做时:

procList[pid][i] = ...

您正在访问一个尚不存在的 entry 对象:std::vector 默认构造函数将其设为空,其大小为 0。这具有未定义的行为


解决方案

  • 您可以在向量(及其子向量!)上使用resize()add default elements
  • 或者您可以在向量的construction 处提供默认元素:
  • 或者您可以使用大括号初始化器直接初始化您的向量。

示例:

vector< vector<entry> > processVector(10); // will have 10 default constructed entry objects.
vector< vector<entry> > eventVector(10);   // will have 10 default constructed entry objects.

for(auto& v : processVector)
   v.resize(10);
for(auto& v : eventVector)
   v.resize(10);

注意事项:

  • 您应该检查每个 I/O 操作的返回
  • 在你的向量上使用at() 成员函数而不是operator[] 将为你检查边界,你会得到类似的东西;

在抛出 'std::out_of_range' 的实例后调用终止
what(): 向量::_M_range_check

【讨论】:

  • 好的,我在玩这些想法,我想将 main() 函数中的向量更改为 vector&lt; vector&lt;entry&gt; &gt; processVector(10); 之类的东西吗?这样做之后,我仍然有一个错误,认为at() 方法确实给了我你描述的错误。
  • 是的,您需要这样做,但对于您的 10 个子向量中的每一个,您都需要这样做!
  • 哦,伙计,在玩了一会儿之后,我让它工作了。谢谢!作为记录,问题确实是我没有调整向量(和子向量)的大小。起初,我没有意识到需要以这种方式初始化子向量,但现在我明白了。谢谢!它似乎工作得很好,现在,或者至少,已经停止了段错误。
猜你喜欢
  • 2021-08-05
  • 2017-03-14
  • 1970-01-01
  • 2014-08-18
  • 2017-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
相关资源
最近更新 更多