从函数返回 char* 不起作用

2022-01-12 00:00:00 pointers char c++

Visual Studio c++ 显示第 24 行的字符串"有一个数组元素,但顶部包含用户输入的所有文本.但是当我发送到 PutString() 时,它就消失了.为什么?

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++] != '
' );
    c[i] = '';
    // PutString( c );
    return c;
}

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

推荐答案

因为 cGetString 中的一个局部变量,而你返回它的地址,之后它就消失了(移出范围).这是未定义的行为――你不能使用超出范围的东西.事实上,如果你通过 gcc 运行它,它会非常明确地告诉你:

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];

进入:

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

(当然,记得最终释放/删除它).

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

即使当您从 GetString 返回时,您可能在调试器中看到它,但仍不能保证符合标准.

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

无论如何,下一次堆栈操作(例如调用 PutString)很有可能会清除信息.

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

这是一个以 new/delete 方式执行此操作的 C++ 版本:

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++] != '
');
    c[i] = '';
    return c;
}                                 // ... past here ...

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

<小时>

我还应该提到,可能有更好的方法在 C 中获取基于行的输入 (fgets 或查看 更早的我的答案)和 C++(例如 string getline 和char 数组 getline).


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).

相关文章