有时,我看到在存储的持续时间和where之间确实存在各种概念的混合。这是因为有时我看到以下语句:
int i; // This is in the stack!
int* j = new int; // This is in the heap!
但是这真的是100%的时间吗? C ++是否确保where进行存储?还是由编译器决定?
存储位置是否与持续时间无关?
例如,使用这两个摘要:
void something()
{
int i;
std::cout << "i is " << i << std::endl;
}
vs:
void something()
{
int* i = new int;
std::cout << "i is " << i << std::endl;
delete i;
}
i
的生命周期或多或少都相等,它是在块的开头创建并在块的结尾删除的,在这里编译器可以只使用堆栈(我不知道!),并且相反也可能发生:
void something()
{
int n[100000000]; // Man this is big
}
vs:
void something()
{
int* n = new int[100000000];
delete n;
}
这两种情况应该放在堆中以避免堆栈溢出(或者至少是到目前为止我所知道的...),除了存储持续时间之外,编译器是否也考虑到了这一点?
C ++是否确保存储在哪里进行?还是由编译器决定?
当您声明类似变量时:
int i;
它具有自动存储。它确实可以在堆栈上,但是如果有足够的寄存器,通常只为其分配一个寄存器。从理论上讲,编译器为此变量分配堆内存也是有效的,但实际上这不会发生。
当您使用new
时,实际上是由标准库为您分配内存。通过默认,它将使用堆。但是,从理论上讲,它也可以在堆栈上分配内存,但是这样做当然是错误的,因为当您从调用new
的函数返回时,任何堆栈存储都会消失。
实际上,new
只是一个运算符,就像+
一样,您可以重载它。通常,您可以在一个类中重载它,但是也可以重载全局new
运算符(以及类似的delete
运算符),并让它从您想要的任何位置分配存储空间。
存储位置是否与持续时间无关?
原则上是,但是在实践中,仅具有函数生存期的自动变量被放置在堆栈上,而使用
new
分配的数据通常旨在使调用它的函数寿命更长,并且在堆上。
这两种情况应该放在堆中以避免堆栈溢出(或者至少是到目前为止我所知道的...),除了存储持续时间之外,编译器是否也考虑到了这一点?
据我所知,GCC和Clang从未对具有自动存储的变量使用堆分配,无论它们的大小如何。因此,您必须自己使用
new
和delete
,或使用为您管理存储的容器。如果仅在其中存储少量元素,则某些容器(例如std::string
)将避免堆分配。
存储位置是否与持续时间无关?