【问题标题】:Error returning char* in c++ function [duplicate]在c ++函数中返回char *时出错[重复]
【发布时间】:2017-01-14 23:58:11
【问题描述】:

我有这个功能:

char* return_string(){
    char buffer[] = "Hi world!";
    return buffer;
}

bool test08()
{
    char compare[] = "Hi world!";
    int result = strcmp(compare,return_string());
if (result == 0) return true;
return false;
}
int main()
{
if(test08) printf("\nTRUE");
else printf("\nFALSE");
}

为什么这段代码在c++ Shell 中运行,而在代码块 v. 13.12 中却没有(分段错误);如果我将我的 char buffer[]= 声明更改为 char *buffer=; 它将起作用我是 C++ 的初学者(很容易知道)所以请清楚......

【问题讨论】:

  • 这是未定义的行为。您正在返回一个指向局部变量的指针。
  • 不要发送无关语言的垃圾标签。

标签: c++ string buffer string-literals


【解决方案1】:

只需将函数return_string改成如下方式

const char* return_string(){
    const char *buffer = "Hi world!";
    return buffer;
}

原函数实现的问题在于数组buffer是函数的本地数组,具有自动存储时长,退出函数后不会存活。

在修改后的函数中使用了一个具有静态存储持续时间的字符串文字。所以你可以返回一个指向字符串字面量第一个字符的指针。

函数test08可以写得更简单

bool test08()
{
    char compare[] = "Hi world!";
    return strcmp( compare, return_string() ) == 0;
}

【讨论】:

    【解决方案2】:

    这个:

    char* return_string(){
        char buffer[] = "Hi world!";
        return buffer;
    }
    

    复制字符串“Hi world!”进入局部变量buffer,然后返回该局部变量 - 如果您尝试使用该返回值,则会导致未定义的行为,因为缓冲区在函数退出时被丢弃。

    这个:

       char* return_string(){
           char *buffer = "Hi world!";
            return buffer;
       }
    

    实际上还可以,尽管可能不是您想要的。您将返回字符串文字的开头地址(存储在一个神秘的地方,重新标准),这没关系。在 C++ 中,您会遇到 const 问题。

    【讨论】:

      【解决方案3】:

      您的函数return_string 正在返回指向局部变量buffer 的指针,该变量仅在return_string 的范围内定义。当函数返回时,您返回以前存储buffer 的地址,而存储在该地址中的值不再有效。 好吧,如果你坚持返回一个指向字符的指针,你可以动态分配“Hello World”并且记得稍后释放它

      char * return_string() {
          char local_var[] = "hello world";
          char *buffer = (char *) malloc(sizeof(local_var));
          strcpy(buffer, local_var); // we know that buffer is big enough to hold local_var
          return buffer;
      }
      

      由于存储“hello world”的内存不是函数本地的,所以函数退出时不会被释放。

      另一个(更好的)解决方案是将静态分配的buffer(希望足够大以容纳您的值)传递给return_string,并在那里修改其内容。

      void return_string(char *buffer, size_t buffer_size) {
          strncpy(buffer, "hello world", buffer_size);
      }
      

      【讨论】:

        【解决方案4】:

        您正在返回一个指向缓冲区的指针,但缓冲区变量在函数返回后被销毁。

        您需要将缓冲区变量设为静态。

        【讨论】:

          【解决方案5】:

          这完全是一个答案,但仍然......
          我已经尝试过 CodeBlocks 16.01 (mingw) 并且一切正常。 所以一个快速的建议,总是尝试使用任何软件的升级版本,特别是如果你还在学习过程中。

          【讨论】:

          • 这是一个典型的“未定义行为”意外即使代码错误也能正常工作的典型案例,这使得识别错误变得更加困难。
          • C++ 不能以这种方式工作。仅仅因为它似乎工作并不意味着代码是“好的”。返回局部变量的地址是未定义的行为,无论该行为可能是什么。它可以工作,它可能会失败,如果使用不同的选项编译它可能会失败,它可能今天工作,明天失败,等等。
          猜你喜欢
          • 1970-01-01
          • 2018-05-09
          • 1970-01-01
          • 2018-10-18
          • 1970-01-01
          • 2020-02-21
          • 2013-01-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多