2011-11-17 167 views
4

`我正在尝试编写一个反转两个字符串的程序,虽然我做得非常好,但是当我运行它时,程序一直运行到第26行,然后出现分段错误错误。该程序编译好。我想知道在我的功能中是否有一个简单或明显的问题,我没有看到,任何帮助将不胜感激!分割错误错误

在此先感谢

#include <iostream> 
#include <string> 
using namespace std; 

// Reversing the characters in strings. 

void reverse(string str); 
void swap(char * first, char *last); 

int main() { 
    // declarations and initialization 
    string str1; 
    string str2; 

    cout << "Please enter the first string of characters:\n"; 
    cin >> str1; 

    cout << "Please enter the second string of characters:\n"; 
    cin >> str2; 

    cout << "The strings before reversing are:" << endl; 
    cout << str1 << " " << str2 << endl; 

    // reverse str1 
    reverse(str1); 
    // reverse str2 
    reverse(str2); 

    // output 
    cout << "The strings after reversing: " << endl; 
    cout << str1 << " " << str2 << endl; 

    return 0; 
} 

void reverse(string str) { 
    int length = str.size(); 

    char *first = NULL; 
    char *last = NULL; 
    first = &str[0]; 
    last = &str[length - 1]; 
    for (int i = 0; first < last; i++) { 
     swap(first, last); 
     first++; 
     last--; 
    } 
} 

void swap(char *first, char *last) { 
    char * temp; 

    *temp = *first; 
    *first = *last; 
    *last = *temp; 
} 
+0

哪一行是第26行? – sth

+0

之后输出“反转之前的字符串是......”...... – blaedj

+4

就这样,您知道,您正在将'string'按值传递给'reverse',因此它实际上不会反转字符串。 –

回答

3

在你swap功能,您就可以在temp不指向任何值分配给*temp(这是未初始化)。因此,你的分段错误。

你想这样的:

void swap(char* first, char* last) 
{ 
    char temp = *first; 
    *first = *last; 
    *last = temp; 
} 
6

我不知道在哪里线26,但

char * temp; 
*temp = ... 

无效。 temp应指向char,或(更好)将函数重写为temp a char

塞思卡耐基指出,如果您想修改原稿,您必须通过string作为参考。

void reverse(string& str) { //pass by reference, so origional is modified 
+0

我看到如何更好地工作,但它是为作业,我必须使用字符串,没有参考值... – blaedj

+0

@ user1050853它仍然是一个字符串,你只是通过引用传递它,以便在函数内进行的任何更改都会影响函数外部的值。如果您不通过引用传递它,函数将颠倒它的本地字符串副本,并且当它返回时,反转的将会丢失。 –

+1

@ user1050853如果你绝对拒绝通过引用传递,那么你应该至少返回一个反向字符串的副本... –

2

你的价值,这意味着只有字符串的本地副本将在reverse功能被逆转传递字符串。你应该通过引用来传递它们。

此外,不要直接更改字符串的内存。使用operator[]这样的:

for (size_t beg = 0, size_t end = str.size() - 1; beg < end; ++beg, --end) 
    str[beg] = str[end]; 

所以一起:

void reverse(string& str); // prototype 

.... 

void reverse(string& str) { // note the & which is pass by reference 
    int length = str.size(); 

    for (size_t beg = 0, size_t end = str.size() - 1; beg < end; ++beg, --end) 
     str[beg] = str[end]; 
} 

以及由鸣叫鸭子说,你可能会崩溃的地方被提领其在这里有一个垃圾值指针:

char * temp; 
*temp = ... 

你试图给一些随机存储器分配一个值,这可能会导致你的系统失效。

+0

Upvoted为“不要直接与字符串内存混乱” –

2

其他答案在段错误原因方面有效。

我只是觉得你可能有兴趣知道,你可以轻易地倒过来使用std::stringreverse_iterator的字符串:

std::string reverse(std::string str) { 
    std::string out; 
    for (std::string::reverse_iterator it = str.rbegin(); it != str.rend(); it++) { 
     out += *it; 
    } 
    return out; 
} 

所以,美其名曰:

reverse("foo"); 

...将返回oof

+0

谢谢,这个项目是为了作业,否则我将明确使用 – blaedj

+0

这可能是效率较低的方法之一正确 –

+0

只是因为你不在乎并不意味着没有人这样做,这不是一个微观优化。通过价值获取和返回字符串并通过串联一次构建一个字符的字符串对于大字符串不会有好处。即便如此,我并不是说这不应该被使用,我只是想为将来的读者提供一个_caveat emptor_。 –

0

同样,其他人指出的问题是什么,想告诉你这一点:

void reverse(std::string & str) {  
for (int i = 0, last = str.size() - 1, lim = str.size()/2 ; i < lim;) { 
    std::swap(str[i++], str[last--]); 
} 
} 

我没有测试它彻底,但。