【问题标题】:char* returned from function in cpp [closed]从cpp中的函数返回的char * [关闭]
【发布时间】:2019-12-31 02:14:33
【问题描述】:

返回的 &string[0] 与函数 foo 中的 char* 相同

char* foo(){
    string str="fsafsdf";
    return &str[0];
}

如果上面是合法的,我们可以这样返回一个c风格的字符串

char* foo(){
    string str="fsafsdf";
    str=str+'\0';
    return &str[0];
}

【问题讨论】:

  • “如果上面是合法的” - 它不是。
  • string str 是一个由foo 作用域的局部变量。它将在foo 结束时过期,因此返回对该变量的引用是一个致命缺陷。
  • 但是内存是在堆中为字符串@user4581301分配的
  • "在堆中为字符串分配内存",一旦函数退出就会被释放。
  • 阅读一本关于 C++ 的好书。

标签: c++


【解决方案1】:

这是不合法的。

您将char* 返回给刚刚死去的对象。 str 在遇到函数的结尾大括号 } 时就不再存在。您正在返回一个悬空指针,它没有指向任何有用的东西。

【讨论】:

  • “非法”实际上是您最不担心的问题。这实际上可能比这更糟糕:起初它可能只是看起来有效。然后你开始看到奇怪的结果并经历“无法解释的”崩溃。特别是如果您的程序有多个线程。
  • 我最喜欢的是Great Comdex Crash of '98。在比尔·盖茨上台炫耀之前,你认为演示成功了多少次?如果一个隐藏的错误要弹出,那就是它会让你被解雇的时候。或者更糟的是,杀人。
【解决方案2】:

如果上面是合法的

语法正确。

它在语义上正确吗?这取决于您如何处理指针。

线

return &str[0];

返回一个指向在函数返回后将不再存在的对象的指针。该指针是调用函数中的一个悬空指针。

如果您尝试取消引用指针,您的代码会受到未定义行为的影响。

if ( *(foo()) == 'a' ) { ... }   // Not OK.

如果您只是将指针用作指针而不取消引用它,则代码应该没问题。例如,您可以将返回的值与nullptr 进行比较。

if ( foo() == nullptr ) { ... }  // OK.

轶事说明

我已经看到商业部署的代码使用函数局部变量的地址来推断堆栈在平台中是向上还是向下。

char* foo()
{
   char c;
   return &c;
}

bool stackGrowsUp()
{
   char c;
   return (&c < foo());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-16
    • 2021-12-26
    • 1970-01-01
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    相关资源
    最近更新 更多