2016-06-13 12 views
6

La mia funzione stackAlloc simile a questa:violazione di accesso quando si utilizza alloca

void* stackAlloc(size_t size) { 
    if (size > maxStackAllocation) 
     return malloc(size); 
    else 
     return _alloca(size); 
} 
void stackAllocFree(void *ptr, size_t size) { 
    if (size > maxStackAllocation) { 
     free(ptr); 
    } 
} 

Se cambio così la funzione stackAlloc utilizzare sempre malloc invece di alloca tutto funziona.

ho cambiato la funzione di una macro, e ora il suo lavoro come previsto:

#define maxStackAllocation 1024 
#define stackAlloc(size) \ 
(\ 
    (size > maxStackAllocation)? \ 
     malloc(size): \ 
     _alloca(size) \ 
) 

#define stackAllocFree(ptr, size) \ 
(\ 
    (size > maxStackAllocation)? \ 
     free(ptr): \ 
    void() \ 
) 
+0

Qual è il valore di 'maxStackAllocation'? Suggerisco di leggere anche tutti gli avvertimenti sulla pagina di documentazione per 'alloca'. –

+0

il suo 1024, alloco solo 124 byte qui – hidayat

+0

http://stackoverflow.com/a/1029951/366904 (dal momento che Vulkan è apparentemente un API C, perché non utilizzare array di lunghezza variabile?) –

risposta

9

Supponendo che si sta in esecuzione su Windows, dal momento che il codice chiama _alloca(), per il MSDN documentation:

_alloca alloca dimensioni byte dallo stack di programmi. Lo spazio allocato viene automaticamente liberato quando la funzione chiamante termina

Si noti che la memoria viene liberata quando si esce dalla funzione di chiamata, il che presumo significa anche che la funzione di chiamata ritorna.

tuo codice:

void* stackAlloc(size_t size) { 
    if (size > maxStackAllocation) 
     return malloc(size); 
    else 
     return _alloca(size); 
} 

rendimenti, liberando la memoria ottenuta tramite _alloca().

+1

fuori rotta, grazie :) – hidayat

+1

Mi chiedo se questo si applica se la funzione è stata contrassegnata come 'static inline __forceinline'. –

+2

@JonathonReinhart, naturalmente si applica anche lì. 'alloca' non è un malloc" reale ", ma sottrae più spazio dallo stackpointer.Ciò significa che verrà SEMPRE automaticamente liberato, poiché la CPU si prenderà cura di ciò. Quindi non importa se una funzione è in linea o meno. – Devolus

3

From the man page,

Questo spazio temporaneo si libera automaticamente quando la funzione che ha chiamato alloca() restituisce al chiamante.

Pertanto, ogni volta che viene ripristinata la funzione stackAlloc, la memoria verrà automaticamente liberata.

0

Questo funziona, ma vorrei consigliare contro l'uso in produzione:

#include <iostream> 
#include <alloca.h> 

auto stackAlloc(const size_t size) 
{ 
    return [size](){ return alloca(size); }; 
} 

int main() { 
    char *ch = (char *)stackAlloc(40000)(); 
    ch[39999] = '\0'; 

    return 0; 
} 

controprova: se diminuisco il parametro di stackalloc, non funziona (che è il comportamento previsto qui) tatto libero di aggiungere il controllo, ecc. nello stackAlloc (o restituendo lambda diversi o facendo fare il controllo al lambda).

Problemi correlati