1

I'm fairly new to C++ and thus trying to understand exactly how pointers and references work. Thus I've a simple program that should reference a string ans return a reference to another string. I don't want to copy either. Here's the code

#include <iostream>
#include <cstdlib>
#include <string>

std::string& string_reverse(std::string& str){
  std::string rev = "";
  for(int i= str.length() -1; i >=0; i--){
    rev+=str[i];
  }
  return &rev;

}

int main(){
  std::string s="";
  std::cout<<"Please enter a string..."<<std::endl;
  std::cin>>s;
  std::cout<< string_reverse(s)<<std::endl;

}

However my code throws up a lot of errors. It would really help if someone can elaborate on the different ways this can be done and the underlying reason for each and which is the right way.

  • 2
    "return a reference to another string" - which, being local to the function, is destroyed before you can do anything with it. Either return by value, or reverse the passed string in place and return either nothing, or a reference to that. – Mike Seymour Feb 19 '15 at 16:29
  • 2
    The function is declared to return a reference, but you attempt to return a *pointer*, the address-of operator `&` results in a pointer. But there are worse problems than that after you fix that simple problem, namely that you return a reference to a local variable, a variable which goes out of scope once the function exits and you are left with a dangling reference and using that will lead to [*undefined behavior*](http://en.wikipedia.org/wiki/Undefined_behavior). – Some programmer dude Feb 19 '15 at 16:29
  • 1
    Generally speaking, you should include the errors in your question when you ask questions like this. Not only do you make things easier on the readers, but it gives them a chance to teach you how to read the errors so you can figure things out yourself! –  Feb 20 '15 at 03:51

4 Answers4

2

First of all, you don't return a reference for scope local variables

std::string& string_reverse(std::string& str){
        // ^

change that to

std::string string_reverse(std::string& str){

A reference can't be returned here, because the rev variable will be destroyed after the function returns (see also Can a local variable's memory be accessed outside its scope?).

Secondly you don't use & to create a reference:

 return &rev;
     // ^

That will take the address of rev (i.e. a pointer). You simply write (for either case)

 return rev;

Last but not least you don't need to pass a non const reference for the input parameter. It's better to write

std::string string_reverse(const std::string& str){ 
                        // ^^^^^

if the function doesn't change str.

Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
0

This will fix your errors

#include <iostream>
#include <cstdlib>
#include <string>

std::string string_reverse(std::string& str){   // made change here
  std::string rev = "";
  for(int i= str.length() -1; i >=0; i--){
    rev+=str[i];
  }
  return rev;        // made change here

}

int main(){
  std::string s="";
  std::cout<<"Please enter a string..."<<std::endl;
  std::cin>>s;
  std::cout<< string_reverse(s)<<std::endl;

}

The problem with your code, as suggested by others is that the variable rev will be destroyed after the function returns ( It becomes out of scope ), and your code causes Undefined Behaviour.

Here are some links you might want to read ( These links can provide you with more information than I can, but you must have patience to read all of it ).

http://www.cs.fsu.edu/~myers/c++/notes/references.html

http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/

http://www.tutorialspoint.com/cplusplus/cpp_function_call_by_reference.htm

http://www.cplusplus.com/articles/z6vU7k9E/

Arun A S
  • 6,421
  • 4
  • 29
  • 43
0

You're mixing references and addressses, get rid of both and it'll work:

std::string string_reverse(std::string& str){
    std::string rev = "";
    for(int i= str.length() -1; i >=0; i--){
        rev+=str[i];
    }
    return rev;

}
Paul Evans
  • 27,315
  • 3
  • 37
  • 54
  • Ok I got it the code compiled, but is there any other way to do it. I'm trying to understand passing by reference better. –  Feb 19 '15 at 16:43
  • `rev` is created on the stack in local scope so you don't want to pass a reference to it out of `string_reverse` (its scope)! Any decent compiler won't actually do any copying but will construct the underlying `string` object where it's gonna end up. – Paul Evans Feb 19 '15 at 16:49
0

The actual error is that you return a reference to something that will be destroyed out of scope.

Xxxo
  • 1,784
  • 1
  • 15
  • 24