我是 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);
}
}
答案 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;
}