存储持续时间与C ++中的位置

问题描述 投票:2回答:2

有时,我看到在存储的持续时间和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++ memory memory-management storage-duration
2个回答
0
投票

C ++是否确保存储在哪里进行?还是由编译器决定?

当您声明类似变量时:

int i;

它具有自动存储。它确实可以在堆栈上,但是如果有足够的寄存器,通常只为其分配一个寄存器。从理论上讲,编译器为此变量分配堆内存也是有效的,但实际上这不会发生。

当您使用new时,实际上是由标准库为您分配内存。通过默认,它将使用堆。但是,从理论上讲,它也可以在堆栈上分配内存,但是这样做当然是错误的,因为当您从调用new的函数返回时,任何堆栈存储都会消失。

实际上,new只是一个运算符,就像+一样,您可以重载它。通常,您可以在一个类中重载它,但是也可以重载全局new运算符(以及类似的delete运算符),并让它从您想要的任何位置分配存储空间。

存储位置是否与持续时间无关?

原则上是,但是在实践中,仅具有函数生存期的自动变量被放置在堆栈上,而使用new分配的数据通常旨在使调用它的函数寿命更长,并且在堆上。

这两种情况应该放在堆中以避免堆栈溢出(或者至少是到目前为止我所知道的...),除了存储持续时间之外,编译器是否也考虑到了这一点?

据我所知,GCC和Clang从未对具有自动存储的变量使用堆分配,无论它们的大小如何。因此,您必须自己使用newdelete,或使用为您管理存储的容器。如果仅在其中存储少量元素,则某些容器(例如std::string)将避免堆分配。


0
投票

存储位置是否与持续时间无关?

© www.soinside.com 2019 - 2024. All rights reserved.