在 C++ 索引程序中使用向量时出现分段错误 11

Posted

技术标签:

【中文标题】在 C++ 索引程序中使用向量时出现分段错误 11【英文标题】:Segmentation fault 11 when using vectors in C++ concordance program 【发布时间】:2014-12-15 00:43:12 【问题描述】:

对于初学者,这里是 C++ 和编码新手,提前道歉。我一直在开发一个程序,该程序可以创建文本文件与单词出现次数以及单词出现在哪一行的一致性。预期输出的简要示例:

A 在第 1 3 5 行出现 9 次

AND 在第 2 4 行出现 3 次

我首先只使用数组编写程序,我已经成功运行。我现在正在尝试使用向量而不是数组来重写它,基本上我不知道在声明向量之后我在做什么。我有我的矢量版本可以编译和链接没有错误,但是当我运行它时,我得到一个“分段错误 11”错误。据我了解,发生此错误的原因是因为我试图访问尚未分配的内存。我正在粘贴我迄今为止在下面编写的整个代码。如果有人可以帮助我,或者指出我需要做些什么来实现这一点,那就太棒了。我知道我需要推送 push_back 方法,但我不知道在哪里。我意识到这对你们中的大多数人来说可能是初级的,但我只是想把所有这些都包起来。再次,非常感谢 -

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector> 

using namespace std;

void copy(vector<int> fromarr, vector< vector<int> > toarr, int index)

    for (int i = 0; i <= fromarr[0]; i++)
    
        toarr[index][i] = fromarr[i];
    


void copy(vector< vector<int> > fromarr, vector<int> toarr, int index)

    for (int i = 0; i <= fromarr[index][0]; i++)
    
        toarr[i] = fromarr[index][i];
    



int search(vector<string> array, int len, string target)

    for(int i = 0; i < len; i++)
    
        if(array[i] == target) return i;
    
    return -1;


void sort(vector<string> wordarray, vector<int> linecount, vector< vector<int> >   linenumbersarray, int length)

    int minpos = 0;

    for(int i = 0; i < length; i++)
    
        minpos = i;
        for (int j = 0; j < length; j++)
        
            if(wordarray[j] > wordarray[minpos]) minpos = j;
            string tempword = wordarray[i];
            int tempcount = linecount[i];
            vector<int> tempnums;
            copy(linenumbersarray, tempnums, i);

            wordarray[i] = wordarray[minpos];
            linecount[i] = linecount[minpos];
            copy(linenumbersarray[minpos], linenumbersarray, i);

            wordarray[minpos] = tempword;
            linecount[minpos] = tempcount;
            copy(tempnums, linenumbersarray, minpos);
        
    



int main(int argc, char* argv[])


    vector<string> wordarray;

    vector<int> linecount;

    vector< vector<int> > linenumbersarray;

    int arrayposition = 0;

    int linenumber = 1;

    int wordlength = 0;


    ifstream infile;
    infile.open(argv[1]);

    string aline;
    while (getline(infile, aline))
    

        istringstream theline(aline);
        string aword;

        while (theline >> aword)
        

            int isupdated = search(wordarray, wordlength, aword);
            if (isupdated == -1)
            
                wordarray[wordlength] = aword;
                linecount[wordlength] = 1;
                linenumbersarray[wordlength][0] = 1;
                linenumbersarray[wordlength][1] = linenumber;
                wordlength = wordlength + 1;
            
            else
            
                linecount[isupdated] = linecount[isupdated] + 1;
                if (linenumbersarray[isupdated][linenumbersarray[isupdated][0]] != linenumber)
                    (linenumbersarray[isupdated][++linenumbersarray[isupdated][0]] = linenumber);
            

        
        linenumber = linenumber + 1;
    

    sort(wordarray, linecount, linenumbersarray, wordlength);


    for (int i = 0; i < wordlength; i++)
    
        ostringstream out;
        for (int j = 1; j <= linenumbersarray[i][0]; j++)
        
            out << linenumbersarray[i][j];
            j != linenumbersarray[i][0] ? out << " " : out << ".";
        
        cout << wordarray[i] << " occurs " << linecount[i] << " time(s) on lines " << out.str() << endl;
        out.flush();
    


【问题讨论】:

第一印象:你想通过引用或常量引用传递向量等,而不是作为整个结构,而不是向量的向量,你可能想要一个映射到向量,或者更好的是将字符串映射到包含其计数及其出现的行列表的类或结构。 Segmentation fault: 11 while printing dynamic arrays的可能重复 您需要了解 C++ 中的 references 是什么,如何使用它们,以及基于迭代器的算法在现代 C++ 程序中如何经常受到青睐。其中的大部分代码对于C++ standard library 中已经提供的函数是多余的,或者根本不需要。 【参考方案1】:

你如何填充你的向量? 使用 push_back 函数填写。

vector<int> v; // an empty container
v.push_back(10); // now it has one element - an integer 10

使用 size() 函数获取向量大小,不要像在少数函数(排序、搜索)中那样传递长度参数

另一种迭代 stl 容器(向量是容器)的方法是使用迭代器

for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
 int a = *it; /*gives you an element of the container*/ 

使用大小或迭代器会阻止您访问未分配的内存 - 这是您的问题

不要在不检查向量边界的情况下使用运算符 []。

if (i < v.size()) v[i]; //an element

这是您的搜索功能的两种变体

int search(vector<string> const &array, string const &target)

    for(int i = 0; i < array.size(); i++)
    
        if(array[i] == target) return i;
    
    return -1;


vector<string>::const_iterator search(vector<string> const &array, string const &target)

    for(vector<string>::const_iterator it = array.begin(); it != array.end(); ++it)
    
        if(*it == target) return it;
    
    return array.end();

更好的搜索方法是使用 std::find 函数,但是当您对 STL 更熟悉时,可以将其留到以后使用。 std::find 与上述搜索的第二个变体相同。

vector<string>::iterator it;
it = find (myvector.begin(), myvector.end(), target);
if (it != myvector.end())
    std::cout << "Element found in myvector: " << *it << '\n';
else
    std::cout << "Element not found in myvector\n";

【讨论】:

以上是关于在 C++ 索引程序中使用向量时出现分段错误 11的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中使用向量时出现分段错误?

在 C++ 中使用向量时出现分段错误

在 C++ 中操作向量时出现分段错误

添加向量时出现分段错误。 (C++)

在 C++ 中比较来自向量的字符串时出现分段错误

在向量中搜索时出现分段错误