为什么在从函数返回数组时需要将数组声明为静态。 (C ++)

时间:2017-08-17 13:48:07

标签: c++ pointers static

我已经知道 digits[3] 存储类允许本地变量在程序的持续时间内继续存在。

我想知道为什么需要将int* getDigits(int input) { const int TEN = 10; int toStore; int digits[3]; /* this array (static) */ for (int i = 0; i < 3; ++i) { toStore = input % TEN; digits[i] = toStore; input = input / TEN; } return digits; } int main(int argc, char const *argv[]) { int* ptr; ptr = getDigits(123); for (int i = 0; i < 3; ++i) { std::cout << *( ptr+i ) << std::endl; } return 0; } 数组声明为静态。如果我没有将其声明为静态,除了编译错误之外会发生什么。

P.S。我在处理C ++中的指针或内存地址方面很陌生。

虽然我对C ++中有关作用域的堆栈内存分配有点了解。

ParameterizedTypeReference<ItemListJSON<SalonJSON>> typeRef = new ParameterizedTypeReference<ItemListJSON<SalonJSON>>() {};

2 个答案:

答案 0 :(得分:4)

您正在返回指向函数本地数组的指针。如果将其声明为static,则表示数组的生命周期延长到程序结束,因此调用代码可以取消引用从函数返回的指针。如果您没有将其声明为static,那么它就是&#34;自动&#34;当块(函数体)结束时,其生命周期结束的变量,因此取消引用返回指向数据的指针是未定义的行为。

无论如何,这些都不是典型的正确解决方案。首先,如果函数被调用两次,则第二次调用可能会更改第一个结果指向的数据。更典型的解决方案是让函数将指针(可能是shared_ptrunique_ptr)返回到使用new int[3]动态分配的数组。另一个解决方案是让函数创建并返回一个std::array<int, 3>,这是一个适当的类类型,可以通过值返回(只有C风格的数组不能通过函数的值返回)。

答案 1 :(得分:2)

本地变量上使用的static关键字有两点会影响变量的生命周期初始化

1。 如果您要在以下函数中声明变量非静态

int* getDigits(int input)
{
   int digits[3]; /* local variable that dies on return */
   ...
   return digits;
}

数组digits 未初始化生命周期仅限于函数内部,因为它位于堆栈上。如果从函数返回,对象的生命周期结束,并且通过返回指针的访问是未定义,这可能并且可能会在程序崩溃时结束。

2。 但是如果你声明数组静态如:

int* getDigits(int input)
{
   static int digits[3]; /* local variable that survives return */
   ...
   return digits;
}

它将零初始化并且生命周期将在函数结束后继续存在,因为它的内存位于程序的数据段中不是堆栈段。您返回的指针将指向有效的内存。

第一个解决方案将以未定义的行为结束,第二个解决方案不是最佳的,因为对getDigits()函数的第二次调用将改变静态变量digits,可能是来自第一个调用点的指针到。

最好使用new int[3]动态分配内存,或者将要更改的数组作为参数传递。此外,还可以使用可以按值复制的C ++的std::array<int, 3>std::vector<int>(3)。这一切都会导致函数的多次调用返回新的变量。