如何理解和修复此代码中的Segmentation错误?

时间:2013-11-25 03:33:21

标签: c++ vector static segmentation-fault

我是 C ++ Primer 5th edition 的新手,其中包括:

  

练习6.33:编写一个递归函数来打印向量的内容。

我的代码,如下所示,编译时没有错误也没有警告。在将第一个项目添加到向量中之后,函数vector_print()通常会打印向量。但是在添加第二个项目之后,程序被操作系统终止。

我试过调试。正在执行语句cout << *it <<" ";时生成一个分段错误。它就像:

下级停止是因为它收到了来自操作系统的信号。

信号名称: SIGSEGV 信号含义: 分段错误

我读了一下这个错误,但仍然没有得到它。谁能告诉我如何理解它并解决这个问题?:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

template<class T>
void  vector_print(const vector<T> &_v);

int main()
{
    string s;
    vector<string> v;

    cout<<"Please Enter:\n";
    while(cin>>s)
    {
        v.push_back(s);
        cout <<"the vector is:  --";
        vector_print(v);
    }
}

template<class T>
void vector_print(const vector<T> &_v)
{
    static typename vector<T>::const_iterator it = _v.begin();
    cout << *it <<" ";

    ++it;
    if(it != _v.end())
    {
        vector_print(_v);
    }
}

3 个答案:

答案 0 :(得分:5)

有一些问题,但主要问题是这一行:

static typename vector<T>::const_iterator it = _v.begin();
^^^^^^

由于it静态,它只会被初始化一次,之前对it的所有修改都将对后续调用vector_print生效。

如果 vector 永远不会被修改it已经在 end ,因此在后续调用vector_print这一行:

cout << *it <<" ";

将取消引用 end 。如果您确实修改了向量,那么对push_back的调用可能会使it无效,则链接的引用会显示:

  

如果new size()大于capacity(),则所有迭代器和引用(包括last-the-end迭代器)都将失效。否则只有过去的结束迭代器无效。

如果没有先检查它是否结束,就不应该增加迭代器

这是解决问题的一种更简单的方法:

template <typename Iterator>
void printVector( Iterator first, Iterator last)
{
    if( first != last )
    {
        std::cout << *first << " " ;
        printVector( std::next( first ), last ) ;
    }
}

你可以像main那样调用函数:

printVector( v.begin(), v.end() ) ;

答案 1 :(得分:1)

您可以在不先检查它是否等效于_v.end的情况下递增迭代器。增加等于end的迭代器是非法的。此外,vector_print无休止地循环。

答案 2 :(得分:0)

#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

void print_vector(vector<int>::iterator i, vector<int>::iterator j)
{
  if (i != j)
  {
    cout << *i++ << " ";
    print_vector(i, j);
  }
  else
  {
    cout << endl;
  }
}

int main()
{
  vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  print_vector(v.begin(), v.end());
  return 0;
}