windows - Ring til \_freea virkelig nødvendigt?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg udvikler på Windows med DevStudio, i C/C ++ uhåndteret.


Jeg vil tildele lidt hukommelse på stakken i stedet for bunken, fordi jeg ikke ønsker at skulle beskæftige mig med at frigive denne hukommelse manuelt (jeg ved om smarte pegere og alle de ting. Jeg har et meget specifikt tilfælde af hukommelsesallokering, jeg har brug for at håndtere), ligner brugen af ​​A2W () og W2A () makroer.


\_alloca gør det, men det er udskrevet. Det anbefales at bruge malloca i stedet. Men \_malloca dokumentation siger, at et opkald til \_\_\_ freea er obligatorisk for hvert opkald til \_malloca. Det besejrer så mit formål at bruge \_malloca, jeg vil bruge malloc eller ny i stedet.


Nogen ved, om jeg kan komme væk med ikke at ringe \_freea uden at lække og hvad påvirker internt?


Ellers vil jeg ende-up bare ved hjælp af afskrevet \_alloca funktion.

Bedste reference


Det er altid vigtigt at ringe \_freea efter hvert opkald til \_malloca.


\_malloca er som \_alloca, men tilføjer nogle ekstra sikkerhedskontroller og forbedringer til din beskyttelse. Som følge heraf er det muligt for \_malloca at allokere på bunken i stedet for stakken. Hvis dette sker, og du ikke ringer \_freea, vil du få en hukommelseslækage.


I debug-modus allokerer \_malloca ALTID på bunken, så det skal også frigøres.


Søg efter \_ALLOCA\_S\_THRESHOLD for detaljer om hvordan tærsklerne virker, og hvorfor \_malloca eksisterer i stedet for \_alloca, og det skal give mening.





Redigere:


Der har været kommentarer, der tyder på, at personen kun fordeler sig på bunken og bruger smarte peger mv.


Der er fordele ved at stakke tildelinger, som \_malloca vil give dig, så der er grunde til at have lyst til at gøre dette. \_alloca vil fungere på samme måde, men er meget mere tilbøjelige til at forårsage en stack overløb eller andet problem, og desværre giver ikke gode undtagelser, men har tendens til kun at rive din proces. \_malloca er meget sikrere i denne henseende og beskytter dig, men omkostningerne er, at du stadig skal frigøre din hukommelse med \_freea, da det er muligt (men usandsynligt i frigivelsestilstand), som \_alloca vil vælge at allokere på bunken i stedet for stak.


Hvis dit eneste mål er at undgå at skulle frigøre hukommelse, vil jeg anbefale at bruge en smart pointer, der håndterer hukommelsesfriheden for dig, da medlemmet går uden for rammerne. Dette ville tildele hukommelse på bunken, men vær sikker og forhindre dig i at frigive hukommelsen. Dette vil kun fungere i C ++, selvom - hvis du bruger almindelig ol C, vil denne tilgang ikke fungere.


Hvis du forsøger at allokere på stakken af ​​andre grunde (typisk ydeevne, da stabelfordeling er meget, meget hurtig), vil jeg anbefale at bruge \_malloca og leve med det faktum, at du skal ringe \_freea på dine værdier.

Andre referencer 1


En anden ting at overveje, er at bruge en RAII-klasse til at styre tildelingen - selvfølgelig er det kun nyttigt, hvis din makro (eller hvad som helst) kan begrænses til C ++.


Hvis du vil undgå at ramme bunken af ​​ydeevne, skal du kigge på de teknikker, der anvendes af Matthew Wilson s skabelonklasse (http://www.stlsoft.org/doc-1.9/classstlsoft\_1\_1auto\_\_buffer.html. Dette vil allokere på stakken, medmindre din anmodning om runtime størrelse overstiger en størrelse angivet på compiler tid - så du får hastigheden på ingen heap tildeling for de fleste tildelinger (hvis du størrelsen skabelonen højre), men alt fungerer stadig korrekt, hvis du overskrider denne størrelse. [13]


Da STLsoft har en hel del cruft til at håndtere portabilitetsproblemer, kan du se på en enklere version af auto\_buffer<>, som er beskrevet i Wilsons bog, 'Imperfect C ++'.


Jeg fandt det ret praktisk i et integreret projekt.

Andre referencer 2


For at allokere hukommelse på stakken, erklærer du blot en variabel af den relevante type og størrelse.

Andre referencer 3


Jeg svarede her før, men jeg savnede noget grundlæggende, der betød, at det kun fungerede i fejlfindingstilstand. Jeg flyttede opkaldet til \_malloca til konstruktøren i en klasse, der ville automatisk frigøre.


I debug er det fint, som det altid tildeler på bunken. I frigivelsen fordeles det dog på stakken, og efter retur fra konstruktøren er stakpekeren blevet nulstillet, og hukommelsen tabt.


Jeg gik tilbage og tog en anden tilgang, hvilket resulterede i en kombination af at bruge en makro (eurgh) til at allokere hukommelsen og instantiere et objekt, der automatisk kalder \_freea på den hukommelse. Som det er en makro, er den allokeret i den samme stakramme, og det vil også fungere i frigivelsestilstand. Det er lige så praktisk som min klasse, men lidt mindre rart at bruge.


Jeg gjorde følgende:


class EXPORT\_LIB\_CLASS CAutoMallocAFree
{
public:
    CAutoMallocAFree( void *pMem ) : m\_pMem( pMem ) {}
    ~CAutoMallocAFree() { \_freea( m\_pMem ); }

private:
    void    *m\_pMem;

    CAutoMallocAFree();
    CAutoMallocAFree( const CAutoMallocAFree &rhs );
    CAutoMallocAFree &operator=( const CAutoMallocAFree &rhs );
};

#define AUTO\_MALLOCA( Var, Type, Length ) 
    Type* Var = (Type *)( \_malloca( ( Length ) * sizeof ( Type ) ) ); 
    CAutoMallocAFree \_\_MALLOCA\_##Var( (void *) Var );


På denne måde kan jeg allokere ved hjælp af følgende makroopkald, og det frigives, når den øjeblikkelige klasse går uden for rækkevidde:


            AUTO\_MALLOCA( pBuffer, BYTE, Len );
            Ar.LoadRaw( pBuffer, Len );


Mine undskyldninger for at sende noget, der var helt klart forkert!

Andre referencer 4


Hvis du bekymrer dig om at frigøre temphukommelse, og du ved alt om ting som smart-pointers, hvorfor skal du ikke bruge et lignende mønster, hvor hukommelsen frigøres, når den går ud af det?


template <class T>
class TempMem
{
  TempMem(size\_t size)
  {
    mAddress = new T[size];
  }

  ~TempMem
  {
    delete [] mAddress;
  }

  T* mAddress;
}

void foo( void )
{
  TempMem<int> buffer(1024);

  // alternatively you could override the T* operator..
  some\_memory\_stuff(buffer.mAddress);

  // temp-mem auto-freed
}

Andre referencer 5


Hvis du bruger \_malloca(), skal du ringe \_freea() for at forhindre hukommelselækage, fordi \_malloca() kan gøre tildelingen enten på stack eller heap. Det giver mulighed for at allokere på bunke, hvis den givne størrelse overstiger\_ALLOCA\_S\_THRESHOLD værdi. Således er det mere sikkert at ringe \_freea(), som ikke vil gøre noget, hvis tildelingen er sket på stakken.


Hvis du bruger \_alloca(), som synes at være deprecated fra i dag, er der ingen grund til at ringe \_freea() som tildelingen sker på stakken.