Doet std::array<> toewijzing alleen op de stapel garanderen?

Is std::array<int,10>(zonder dat ik newgebruik) gegarandeerd door de C++-Standard in de stapel te worden toegewezen in plaats van in de heap?

Voor alle duidelijkheid, ik bedoel niet new std::array<int, 10>. Ik vraag me vooral af of de standaardbibliotheek newmag gebruiken in zijn implementatie.


Antwoord 1, autoriteit 100%

TL;DR: ja, het ligt op de stapel.


Het langere verhaal:

C++ heeft geen concept van stapel of heap. Dit zijn implementatiedetails, en er is ten minste één platform dat geen traditionele stapel gebruikt (maar eerder een gekoppelde lijst met heaptoewijzingen ervoor).

Het heeft automatische opslag en de gratis winkel. newheeft toegang tot de gratis winkel en variabelen “op de stapel” gaan naar automatische opslag.

In de praktijk moet je, om dingen in de gratis winkel toe te wijzen, het risico lopen een onvoldoende geheugenuitzondering te krijgen. Dus de algemene regel is dat dingen die garanderen dat ze niet weggooien, automatische opslag moeten gebruiken. arraygeeft deze garantie (behalve wat er ook in zit, natuurlijk). Het is ook een aggregaat van gewone oude gegevens, in feite gedwongen om er als volgt uit te zien:

template<class T,std::size_t N>
struct array {
  T __no_fixed_name__[N];
  // non-constructor/destructor methods omitted as they are noise at this point
};

In theorie zou het door de compiler kunnen worden geïmplementeerd via magie die geen echte C++ is, maar dat is niet nodig, dus niemand stoort.

Dus tot slot: ja, std::arraystaat op de stapel.


Antwoord 2, autoriteit 77%

Ik kon geen explicieter antwoord vinden in de standaard, maar [array.overview]/2:

Een array is een aggregaat([dcl.init.aggr]) dat kan worden geïnitialiseerd in een lijst met maximaal Nelementen waarvan typen kunnen worden omgezet in T.

En [dcl.init.aggr]/1:

Een aggregaat is een array of een klasse(clausule [class]) met

  • geen door de gebruiker opgegeven, expliciete of overgenomen constructors([class.ctor]),

Dat dekt het ongeveer. Op geen enkele manier kan een aggregaat geheugen dynamisch toewijzen (of misschien helemaal niets doen tijdens de constructie). Er is alleen een impliciet verklaarde triviale constructor.

Als je new std::array<...>gebruikt, krijg je natuurlijk een array op “the heap”.


Sommigen zijn misschien meer tevreden met wat we kunnen krijgen op cppreference:

std::arrayis een container die arrays met een vaste grootte inkapselt.

Deze container is een geaggregeerd type met dezelfde semantiek als een struct die een C-stijl array T[N]als enige niet-statische gegevenslid bevat.


Ten derde werd std::arraygeïntroduceerd in C++11. Waarom? Bijvoorbeeld om std::vectorop sommige manieren aan te vullen, zoals gebruik in constexpr-functies, waar dynamische toewijzing niet is toegestaan.

Other episodes