adabo
adabo

Reputation: 87

Returning char* from function not working

Visual studio c++ shows that "string" on line 24 has one array element, but the top contains all the text that was input by the user. But when I send to PutString(), it disappears. Why?

#include <stdio.h>

void PutString( const char* pChar ){
    for( ; *pChar != 0; pChar++ )
    {
        putchar( *pChar );
    }
}

char* GetString(){
    char c[100];
    int i = 0;
    do
    {
        c[i] = getchar();
    }while( c[i++] != '\n' );
    c[i] = '\0';
    // PutString( c );
    return c;
}

void main(){
    char* string = GetString();
    PutString( string );
}

Upvotes: 2

Views: 2550

Answers (3)

paxdiablo
paxdiablo

Reputation: 881223

Because c is a local variable within GetString and you are returning its address, after which it disappears (moves out of scope). That's undefined behaviour - you're not allowed to use stuff that's gone out of scope. In fact, if you run that through gcc, it tells you that quite explicitly:

qq.cpp:9: warning: address of local variable ‘c’ returned

If you want to return non-simple things (such as arrays instead of integers or floats, which make a copy for you) from a function, you need to (for example) dynamically allocate it so that it survives function return. Something like changing:

char c[100];

into:

char *c = malloc (100); // or equivalent 'new'.

(and remembering to free/delete it eventually, of course).

Even though you may see it in the debugger when you return from GetString, it's still not guaranteed as per the standards.

In any case, there's a good chance the next stack manipulation (such as calling PutString) will wipe out the information.


Here's a C++ version that does it the new/delete way:

#include <stdio.h>

void PutString (const char* pChar ){
    for (; *pChar != 0; pChar++)
        putchar( *pChar );
}

char* GetString (void) {
    char *c = new char[100];      // memory behind c will survive ...
    int i = 0;
    do {
        c[i] = getchar();
    } while (c[i++] != '\n');
    c[i] = '\0';
    return c;
}                                 // ... past here ...

int main (void) {
    char* string = GetString();
    PutString (string);
    delete[] string;              // ... until here.
    return 0;
}

I should also mention that there are probably better way to get line-based input in both C (fgets or see an earlier answer of mine) and C++ (such as the string getline and the char array getline).

Upvotes: 9

Ed Heal
Ed Heal

Reputation: 59997

You GetString will not work correctly as the string (char c[100]) is put onto the stack. When the function gets to the return this will be deleted.

Either use malloc or pass into the function the array.

Upvotes: 1

codaddict
codaddict

Reputation: 454960

You are returning pointer to a variable that is local to the function in GetString(), when the function returns, the space allocated to the variable is reclaimed.

To fix these you can either dynamically allocate space for the character array or declare it as static so that the lifetime of the variable becomes the entire program.

Upvotes: 2

Related Questions