2011-02-17 100 views
5

我想在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 

回答

8

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

至于为什么这是崩溃的写作,我只能推测。编译器很可能会生成一个调用main中的std::string析构函数来清理返回的std::string对象。由于encrypt实际上不会返回任何内容,析构函数最终会调用一个不存在的对象。应该包含对象的内存可能只包含垃圾数据,而析构函数不会那样。

+0

但他为什么在`〜basic_string`中得到SIG? – osgx 2011-02-17 01:44:11

+0

啊谢谢修复它 – 2011-02-17 01:44:26

+0

我甚至不知道这可以编译。顺便说一下@kernel,别忘了接受正确的答案! – Marlon 2011-02-17 01:46:57

1

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

添加

return "blah blah"; 

除了固定的是,考虑通过字符串参考const,像

std::string const& plain 

干杯&心连心,

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> = 4.6时,Visual Studio> = 2010

5

[C++2003 Standard section 6.6.3-2] Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.

这是一个很容易犯的错误,如果你的编译器不会发出警告。您可以通过启用尽可能多的编译器警告来节省大量调试时间。在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 
相关问题