【问题标题】:Why do char arrays get lost when returning from a function in C++?从 C++ 中的函数返回时,为什么 char 数组会丢失?
【发布时间】:2020-03-06 01:02:40
【问题描述】:

我知道,如果我们在函数中声明变量而不为它们分配内存,那么在函数完成其工作后它们将丢失。

以下代码打印:

(null)
5
char* getString() 
{ 
  char arr[] = "SomeText";
  return arr;  
}      

int getInt()
{
    int b = 5;
    return b;
}

int main() 
{ 
  printf("%s", getString());
  printf("\n");
  printf("%d", getInt());

  return 0; 
} 

arrb 变量都是在堆栈上创建的,所以它们都应该在函数结束时被销毁。我的问题是,为什么变量b 没有丢失而变量arr 丢失了?

【问题讨论】:

  • 未定义的行为。任何事情都有可能发生。
  • 局部变量b丢失,但其由函数返回。如果您将 指针 返回到 b,则情况与 arr 相同。
  • 据我了解,变量 b 使用的内存可以被任何其他东西使用。如果发生这种情况,我也会失去变量 b。 @pmg 为什么值不会丢失?
  • 假设在函数之间传递“事物”是通过信封完成的。当getInt() 到达语句return b; 时,它会将当时包含在变量b 中的值放入信封中。函数getString() 将类似0xdeadbeef 的东西放入信封内(“腐烂的”arr)。
  • 两个函数都返回值。 getInt() 返回一个整数值,getString() 返回一个 char* 值。不幸的是,返回的 char* 值是超出范围且不再存在的数组的地址。

标签: c++ arrays callstack char-pointer


【解决方案1】:

C(并由 C++ 继承)的一个独特且经常令人困惑的特性是,在表达式中使用数组时,它不被视为值的集合,而是(大多数时候)作为指向其第一个元素的指针。 因此,当您从函数返回数组时,您将返回其第一个元素的地址。

取消引用具有自动存储持续时间且不再在范围内的对象的地址会导致未定义的行为。

当您从函数返回值时,该值的副本将返回给调用者。

因此,当您返回一个整数时,调用者会收到该整数值的副本。

如果值是指针,则复制的值是指针。如果指针指向一个无效对象,那么如果指针的接收者试图取消引用指针值,则会导致未定义的行为。


有3个例外:(1)作为&的操作数; (2) 作为sizeof的操作数; (3) 用于初始化数组的字符串文字。在 C++ 中,还有其他例外情况: (4) 作为decltype 的操作数; (5) 作为引用参数的函数参数; (6) 初始化引用变量的对象; ...可能是我忘记的其他东西...

【讨论】:

    【解决方案2】:

    getIntgetString 都返回一个值。

    getInt 返回一个 int 值 5。它在调用者中仍然是 5。

    getString 返回一个指向arrchar * 值。当调用者收到一个指针时,当函数返回时,它所指向的东西arr 不再存在(在 C 标准的计算模型中)。

    因此,问题不是函数返回的值,而是它的含义。数字 5 保留了它的含义。指向不再存在的事物的指针不会保留其含义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-09
      • 1970-01-01
      • 1970-01-01
      • 2015-08-20
      • 2018-09-03
      • 2013-12-26
      • 2011-10-02
      相关资源
      最近更新 更多