【问题标题】:Returning char* from function not working从函数返回 char* 不起作用
【发布时间】:2012-10-23 19:00:43
【问题描述】:

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

#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 );
}

【问题讨论】:

    标签: c++ pointers char


    【解决方案1】:

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

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

    如果你想从一个函数返回非简单的东西(例如数组而不是整数或浮点数,它们会为你创建一个副本),你需要(例如)动态分配它,以便它在函数返回后仍然存在。有点像改变:

    char c[100];
    

    进入:

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

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

    尽管当您从GetString 返回时,您可能在调试器中看到它,但仍不能保证按照标准。

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


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

    #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;
    }
    

    我还应该提到,在 C(fgets 或参见 an earlier answer of mine)和 C++(例如 string getline 和 char array getline)中可能有更好的方法来获取基于行的输入。

    【讨论】:

    • 嗯。如果超出范围,为什么输出会在十六进制值旁边的“字符串”中显示字符串值?
    • @abado 移出作用域后,变为未定义行为
    • @adabo,所以你看到你得到的输出是不可预测的
    • @adobo,因为对 PutString 的调用覆盖堆栈上的信息。
    【解决方案2】:

    您正在返回指向GetString() 中函数的本地变量的指针,当函数返回时,分配给变量的空间被回收。

    要解决这些问题,您可以为字符数组动态分配空间或将其声明为静态,以便变量的生命周期成为整个程序。

    【讨论】:

    • 我明白了。那么如何正确返回 getchar() 值呢?
    【解决方案3】:

    当字符串 (char c[100]) 被放入堆栈时,您的 GetString 将无法正常工作。当函数返回时,它将被删除。

    要么使用malloc,要么将数组传递给函数。

    【讨论】:

      猜你喜欢
      • 2017-08-08
      • 2019-11-19
      • 1970-01-01
      • 2015-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-16
      • 2018-10-18
      相关资源
      最近更新 更多