-2

I made this little program just to get better understanding of dealing with strings.But i stuck in a small problem. Here is the code.

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

string& add( string&x ){
    string t; // <=  Is this the problem???Declaring local string variable
    cout <<"Size of String :" <<x.size() << endl;
    for(int i=0; i<x.size();i++){
        int  n = x[i] - '0';
        t[i] = n + 2  + '0';
    }
    for(int i=0;i<x.size();i++)
       cout <<"t["<<i<<"]="<<t[i]<<endl;    //This line is showing output as I wanted
    cout <<"\nt = " << t << endl;           // <=why the output of this line is blank?
    cout <<"size of t="<<t.size() << endl;  // <=and why the size of string t is zero?              
    return t;         
}

int main(){
   string a;
   cin >> a ;
   string b = add(a);
   cout << "b =" << b << endl;
   system("pause");
   return 0; 
}

I/p :123

o/p:

size of String :3

t[0]=3 t[1]=4 t[2]=5

t=

size of t = 0

b =

I am having problem with referencing the variable, passing the string as a reference and returning the string.. can anybody help me ??

vsoftco
  • 55,410
  • 12
  • 139
  • 252
KapilSantore
  • 43
  • 1
  • 1
  • 4
  • 3
    You are returning a reference to a local variable. That is undefined behaviour. You should return by value: `string add( const string& x);` – juanchopanza Jul 26 '14 at 15:41
  • possible duplicate of [Can a local variable's memory be accessed outside its scope?](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – πάντα ῥεῖ Jul 26 '14 at 15:42
  • @juanchopanza ; I did as you mention but it is showing same output. – KapilSantore Jul 26 '14 at 16:10
  • The problem is that you say "I want to return a string", but you actually return a reference to a string. – stefan Jul 26 '14 at 16:32

3 Answers3

4

Yes, it is a problem. You end up with a dangling reference. At the exit from the function, the local string t is destroyed, and the returned reference end up referring anything that happens to be at the memory location where t was. Using it later will cause undefined behaviour.

Just return the string by value

string add( /* const */ string&x ) // should use `const` probably if you don't modify x

the compiler is smart enough to avoid un-necessary copies (see copy elision).

PS: You should use += operator to append a char to a string, that is, replace t[i] = n + 2 + '0'; by t[i] += n + 2 + '0';. std::string is a class and the [] operator is used to read/write from an INITIALIZED string (you cannot append by incrementing the counter past the end of the string, and you initial string has length 0). Use its overloaded operator += to append.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • still the code is showing same output... cout << t ; // The output of this line is still blank – KapilSantore Jul 26 '14 at 16:20
  • @KapilSantore I have no idea what you do with `t` in the `for` loop, use a debugger and see what's going on. You are mixing `char`s with `int`s, so be careful. – vsoftco Jul 26 '14 at 16:26
  • @KapilSantore, the problem is with appending `char`'s to the `string` in the `for` loop. You should use `+=` operator to append a char, that is, replace `t[i] = n + 2 + '0';` by `t[i] += n + 2 + '0';`. String is a `class` and the `[]` operator is used to `read/write` from an INITIALIZED string (you cannot append by incrementing the counter past the end of the string, and you initial string has length `0`). Use its overloaded operator `+=` to append. – vsoftco Jul 26 '14 at 16:42
  • `string add( const string&x ){ cout << "size of String :" << x.size() << endl; char* buf = new char[x.size()]; for(int i=0; i – KapilSantore Jul 26 '14 at 17:20
  • @KapilSantore in this case, `buf` is a plain-old-data raw buffer, has memory already allocated. In the other case, the `string` is an object (it is NOT a fundamental type), which internally defines its operations, like indexing with `[]` operator etc. And the operation for appending is overloaded by `operator+=`. – vsoftco Jul 26 '14 at 17:23
  • Thankyou.. it clicked, I made it this way... I made the string t of size of x and initialzed it with '0' `string t(x.size(),'0')` .....and it worked. is this correct? I mean Its showing correct answer but is this efficient way rather declaring a buf(allocating memory) then copy it onto a new string and make buf free. – KapilSantore Jul 26 '14 at 18:07
  • @KapilSantore, yeap, this should work, you now have the string initialized so you can write to it without any problems. And it is fast and efficient also, as you are not reallocating memory by appending. – vsoftco Jul 26 '14 at 18:08
  • Thankyou actually that line clicked- " [] operator is used to read/write from an INITIALIZED string " well it worked thanks again :) – KapilSantore Jul 26 '14 at 18:11
0

I believe using useful functions like itoa and atoi is the best way to convert between integers and strings and its so easier too.

#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;

string add( char * x ){
    int n = atoi(x) + 2;
    char m[10];
    itoa(n, m, 10);
    return m;      
}
int main(){
char a[10];
cin >> a ;
string b = add(a);
cout << "b =" << b << endl;
system("pause");
return 0; 
}
Alireza Majidi
  • 115
  • 1
  • 10
0

After its string t; declaration, t is the empty string. So you are not allowed to assign values to t[0],t[1] etc -- they don't exist. (Technically, t[0] exists as the null terminator of t.cstr(), but let's not go there.)

After your illegal assignments to t[i], the length is still zero. You were lucky not to generate an access violation !

TonyK
  • 16,761
  • 4
  • 37
  • 72