我已经知道 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>>() {};
答案 0 :(得分:4)
您正在返回指向函数本地数组的指针。如果将其声明为static
,则表示数组的生命周期延长到程序结束,因此调用代码可以取消引用从函数返回的指针。如果您没有将其声明为static
,那么它就是&#34;自动&#34;当块(函数体)结束时,其生命周期结束的变量,因此取消引用返回指向数据的指针是未定义的行为。
无论如何,这些都不是典型的正确解决方案。首先,如果函数被调用两次,则第二次调用可能会更改第一个结果指向的数据。更典型的解决方案是让函数将指针(可能是shared_ptr
或unique_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)
。这一切都会导致函数的多次调用返回新的变量。