Sök…


Syntax

  • : :( opt ) new ( expression-list ) ( opt ) new-type-id new-initializer ( opt )
  • : :( opt ) new ( expression-list ) ( opt ) ( type-id ) new-initializer ( opt )
  • : :( opt ) radera cast-expression
  • : :( opt ) radera [] cast-expression
  • std :: unique_ptr < type-id > var_name (ny typ-id ( opt )); // C ++ 11
  • std :: shared_ptr < type-id > var_name (ny typ-id ( opt )); // C ++ 11
  • std :: shared_ptr < type-id > var_name = std :: make_shared < type-id > ( opt ); // C ++ 11
  • std :: unique_ptr < type-id > var_name = std :: make_unique < type-id > ( opt ); // C ++ 14

Anmärkningar

En ledande :: tvingar den nya eller radera operatören att letas upp i global omfattning och åsidosätter eventuella överbelastade klassspecifika nya eller radera operatörer.

De valfria argumenten som följer det new nyckelordet används vanligtvis för att ringa placeringar nya , men kan också användas för att skicka ytterligare information till allokeraren, till exempel en tagg som begär att minnet ska allokeras från en vald pool.

Den tilldelade typen anges vanligtvis uttryckligen, t.ex. new Foo , men kan också skrivas som auto (sedan C ++ 11) eller decltype(auto) (sedan C ++ 14) för att härleda den från initialiseraren.

Initialisering av det tilldelade objektet sker enligt samma regler som initialisering av lokala variabler. Speciellt kommer objektet att initialiseras om initialiseraren inte utelämnas, och när dynamisk allokering av en skalartyp eller en grupp skalartyp finns det ingen garanti för att minnet kommer att nollställas.

Ett arrayobjekt skapat av ett nytt uttryck måste förstöras med delete[] , oavsett om det nya uttrycket har skrivits med [] eller inte. Till exempel:

using IA = int[4];
int* pIA = new IA;
delete[] pIA;  // right
// delete pIA;  // wrong

Stack

Bunten är ett litet minneområde i vilket tillfälliga värden placeras under körning. Tilldelning av data i stacken är mycket snabbt jämfört med tilldelning av heap, eftersom allt minne har tilldelats för detta ändamål.

int main() {
    int a = 0; //Stored on the stack
    return a;
}

Bunken namnges eftersom kedjor med funktionssamtal kommer att ha sitt tillfälliga minne "staplat" ovanpå varandra, var och en använder en separat liten del av minnet.

float bar() {
    //f will be placed on the stack after anything else
    float f = 2;
    return f;
}

double foo() {
    //d will be placed just after anything within main()
    double d = bar();
    return d;
}

int main() {
    //The stack has no user variables stored in it until foo() is called
    return (int)foo();
}

Data lagrade i stacken är bara giltiga så länge som omfattningen som tilldelade variabeln fortfarande är aktiv.

int* pA = nullptr;

void foo() {
    int b = *pA;
    pA = &b;
}

int main() {
    int a = 5;
    pA = &a;
    foo();
    //Undefined behavior, the value pointed to by pA is no longer in scope
    a = *pA;
}

Gratis lagring (hög, dynamisk tilldelning ...)

Termen "heap" är ett allmänt beräkningsuttryck som betyder ett minneområde från vilket delar kan allokeras och omfördelas oberoende av minnet som tillhandahålls av stapeln .

I C++ hänvisar standarden till detta område som Free Store som anses vara en mer exakt term.

Områden med minne som tilldelats från Free Store kan leva längre än det ursprungliga räckvidden som det tilldelades. Data som är för stora för att lagras på bunten kan också tilldelas från Free Store .

Rått minne kan allokeras och fördelas med de nya och ta bort nyckelord.

float *foo = nullptr;
{
    *foo = new float; // Allocates memory for a float
    float bar;              // Stack allocated 
} // End lifetime of bar, while foo still alive

delete foo;          // Deletes the memory for the float at pF, invalidating the pointer
foo = nullptr;       // Setting the pointer to nullptr after delete is often considered good practice

Det är också möjligt att tilldela matriser med fast storlek med nya och ta bort , med en något annan syntax. Arrayallokering är inte kompatibel med icke-arrayallokering, och blandning av de två leder till hög korruption. Tilldelning av en matris tilldelar också minne för att spåra storleken på matrisen för senare radering på ett implementeringsdefinerat sätt.

// Allocates memory for an array of 256 ints
int *foo = new int[256];
// Deletes an array of 256 ints at foo
delete[] foo;

När man använder nytt och raderar istället malloc och free kommer konstruktören och destruktorn att köras (liknar stackbaserade objekt). Det är därför nya och radera föredras framför malloc och gratis .

struct ComplexType {
    int a = 0;

    ComplexType() { std::cout << "Ctor" << std::endl; }
    ~ComplexType() { std::cout << "Dtor" << std::endl; }
};

// Allocates memory for a ComplexType, and calls its constructor
ComplexType *foo = new ComplexType();
//Calls the destructor for ComplexType() and deletes memory for a Complextype at pC
delete foo;
C ++ 11

Från C ++ 11 rekommenderas användning av smarta pekare för att indikera ägande.

C ++ 14

C ++ 14 lade till std::make_unique till STL, ändra rekommendationen för att gynna std::make_unique eller std::make_shared istället för att använda naken ny och ta bort .

Placering ny

Det finns situationer när vi inte vill lita på Free Store för att tilldela minne och vi vill använda anpassade minnesallokeringar med hjälp av new .

I dessa situationer kan vi använda Placement New , där vi kan säga den "nya" operatören att tilldela minne från en fördelad minnesplats

Till exempel

int a4byteInteger;

char *a4byteChar = new (&a4byteInteger) char[4];

I detta exempel är minnet som pekas av a4byteChar 4 byte allokerat till "stack" via a4byteInteger .

Fördelen med denna typ av minnesallokering är det faktum att programmerare kontrollerar allokeringen. I exemplet ovan, eftersom a4byteInteger allokeras på stacken, behöver vi inte ringa ett uttryckligt samtal för att "radera a4byteChar".

Samma beteende kan också uppnås för dynamiskt tilldelat minne. Till exempel

int *a8byteDynamicInteger = new int[2];

char *a8byteChar = new (a8byteDynamicInteger) char[8];

I detta fall kommer minnespekaren från a8byteChar att hänvisa till dynamiskt minne tilldelat av a8byteDynamicInteger . I det här fallet måste vi dock uttryckligen ringa delete a8byteDynamicInteger att släppa minnet

Ett annat exempel för C ++ Class

struct ComplexType {
    int a;

    ComplexType() : a(0) {}
    ~ComplexType() {}
};

int main() {
    char* dynArray = new char[256];

    //Calls ComplexType's constructor to initialize memory as a ComplexType
    new((void*)dynArray) ComplexType();

    //Clean up memory once we're done
    reinterpret_cast<ComplexType*>(dynArray)->~ComplexType();
    delete[] dynArray;

    //Stack memory can also be used with placement new
    alignas(ComplexType) char localArray[256]; //alignas() available since C++11

    new((void*)localArray) ComplexType();

    //Only need to call the destructor for stack memory
    reinterpret_cast<ComplexType*>(localArray)->~ComplexType();

    return 0;
}


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow