为什么在迭代这个字符串时会出现分段错误?

时间:2011-02-17 01:37:33

标签: c++ iterator

我正在尝试用C ++实现一个基本的移位密码。在找出导致分段错误的原因之前,我不能继续前进。 我使用gdb逐步完成代码,问题似乎源于迭代器。

 1 #include <iostream>
 2 #include <string>
 3 
 4 std::string encrypt (std::string plain, int key);
 5 
 6 int main()
 7 {
 8         std::string plaintext;
 9         std::getline(std::cin,plaintext,'\n');
 10        encrypt(plaintext,3);   
 11 }
 12 
 13 std::string encrypt(std::string plain, int key)
 14 {
 15         std::string::iterator ic;
 16         for (ic= plain.begin(); ic != plain.end();++ic)
 17         {
 18                 std::cout <<*ic + key << std::endl;
 19         }
 20 }

错误:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b73ef1 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() () from /usr/lib/libstdc++.so.6

4 个答案:

答案 0 :(得分:8)

您已将encrypt声明为返回std::string,但您不会从该函数返回任何内容。您需要返回一个值,或者需要将返回类型更改为void以指示该函数不返回任何内容。

至于为什么它会像写的一样崩溃,我只能推测。编译器可能已在std::string中生成对main析构函数的调用,以清除std::string返回的encrypt对象。由于encrypt实际上没有返回任何内容,因此析构函数最终会被调用一个不存在的对象。应该包含对象的内存可能只包含垃圾数据,析构函数不喜欢它。

答案 1 :(得分:5)

  

[C ++ 2003标准第6.6.3-2节]流程结束了   功能相当于一个回报   没有价值;这导致了   一个未定义的行为   价值回归功能。

如果您的编译器没有警告您,这是一个非常容易犯的错误。通过启用尽可能多的编译器警告,您可以节省大量调试。在gcc / g ++的情况下,我建议使用“-Wall -Werror”为您正在编写的任何新代码进行编译。使用这些选项,此程序的编译失败,并显示以下消息:

cc1plus: warnings being treated as errors
In function 'std::string encrypt(std::string, int)':
Line 20: warning: control reaches end of non-void function

答案 2 :(得分:3)

编写循环,但将其从使用索引更改为使用迭代器通常是一个错误。如果您打算使用显式循环,那么继续使用索引通常更有意义,至少对于允许随机访问的string这样的东西。迭代器的主要目的是启用未与容器耦合的通用算法。要充分利用迭代器,请将其与算法一起使用:

int main() { 
    std::string plaintext;
    std::getline(std::cin, plaintext);

    std::transform(plaintext.begin(), plaintext.end(), 
                   std::ostream_iterator<char>(std::cout), 
                   std::bind2nd(std::plus<int>(), 3));
    return 0;
}

编辑:自从汉斯帕斯特提出以来,使用lambda表达式的版本将如下所示:

std::transform(line.begin(), line.end(), 
               std::ostream_iterator<char>(std::cout), 
               [](char ch) { return ch+'\03'; });

只有相对较新的编译器支持此功能 - gcc&gt; = 4.6,Visual Studio&gt; = 2010。

答案 3 :(得分:1)

问题是您的encrypt函数缺少return语句。

添加

return "blah blah";

除了修复它之外,请考虑通过引用传递字符串const,如

std::string const& plain

干杯&amp;第h。,