2010-08-10 4 views
3

Pourquoi voudriez-vous jamais utiliser alloca() quand vous pouvez toujours allouer un tampon de taille fixe sur la pile assez grand pour toutes les utilisations? Ce n'est pas une question rhétorique ...Dans quels cas alloca() est-il utile?

+1

voir aussi http://stackoverflow.com/questions/1018853/why-is-alloca-not-considered-good-practice –

+0

'goto' est également considéré comme une mauvaise pratique, mais parfois il est nécessaire. Alloca() est-il nécessaire? –

Répondre

2

Cela peut être utile si la taille de la mémoire tampon varie au moment de l'exécution ou si vous n'en avez besoin que de temps en temps: cela nécessite moins d'espace de pile qu'un tampon de taille fixe dans chaque appel. Particulièrement si la fonction est en haut de la pile ou récursive.

+1

+1 pour la réponse la plus convaincante, jusqu'à présent. Lorsqu'une fonction est récursive, l'allocation de la taille maximale de la mémoire tampon sur la pile peut réduire considérablement le nombre d'appels récursifs max. Donc, l'utilisation de alloca() peut réduire la pénalité de devoir faire face au scénario le plus défavorable. –

+0

Pourriez-vous en dire plus à ce sujet? – KodeWarrior

0

Jamais - cela ne fait pas partie de C++, et pas utile en C. Cependant, vous ne pouvez pas allouer "un tampon statique sur la pile" - les tampons statiques sont alloués au moment de la compilation, et pas sur la pile.

Le point de alloca() est bien sûr qu'il n'est pas de taille fixe, il est sur la pile, et qu'il est libéré automatiquement lorsqu'une fonction se termine. Les deux C++ et C ont de meilleurs mécanismes pour gérer cela.

+2

statique n'est jamais threadsafe, alloca est – user411313

+0

Avez-zr modifier la question? Il lit maintenant, "fixed-sized", pas "static" – Shog9

+0

alloca n'est pas moins une partie de C++ que c'est en C - il est standardisé dans aucun. –

0

Vous pourriez vouloir l'utiliser s'il n'y a aucun moyen de connaître la taille maximale dont vous pourriez avoir besoin au moment de la compilation.

Si vous doit être another question - ce n'est pas standard, et il n'y a aucun moyen de dire si cela peut provoquer un débordement de la pile.

+0

* tapotez sur le dos * pour "Stack Overflow"! –

0

Dans quels cas alloca() est-elle utile?

La seule fois où j'ai vu alloca utilisé était dans Open Dynamics Engine. AFAIK ils allouaient des matrices ÉNORMES avec lui (donc le programme compilé pourrait exiger la pile 100MB), qui étaient automatiquement libérés quand la fonction revient (ressemble à l'arnaque de smartpointer à moi). C'était il y a un bon moment.

Bien que c'était probablement beaucoup plus rapide que new/malloc, je pense toujours que c'était une mauvaise idée. Au lieu de court-circuiter poliment le programme de RAM, il pouvait s'écraser avec un débordement de pile (c'est-à-dire trompeur) lorsque la scène devenait trop complexe à gérer. Pas un bon comportement, OMI, en particulier pour le moteur de physique, où vous pouvez facilement vous attendre à ce que quelqu'un jette quelques milliers de briques dans la scène et voir ce qui se passe quand ils entrent tous en collision à la fois. De plus, vous deviez régler la taille de la pile manuellement - c'est-à-dire sur le système avec plus de RAM, le programme serait toujours limité par la taille de la pile.

un tampon de taille fixe sur la pile assez grand pour convenir à toutes les utilisations? Il ne s'agit pas d'une question rhétorique ...

Si vous avez besoin d'un tampon de taille fixe pour toutes les utilisations, vous pouvez aussi bien le placer dans une variable statique/globale ou utiliser la mémoire de tas.

+1

Comme une arnaque "smartpointer", je suppose que "alloca" a utilisé une machine à voyager dans le temps pour voler l'idée. 'alloca' date de la fin des années 1960, et les pointeurs intelligents sont post-1986 ... Le point a été fait ailleurs à propos de la sécurité des threads comme un positif de alloca que les variables statiques/globales ne partagent pas. Le tas dépend de la manière dont vous l'utilisez, donc pas de 900 caractères. –

+0

@Heath Hunnicutt: "alloca a utilisé une machine à remonter le temps" Open Dynamics Engine n'a pas été écrit dans les années 60. – SigTerm

0

La fonction alloca() n'est pratiquement jamais nécessaire; Pour des raisons d'allocation de mémoire, vous pouvez utiliser malloc()/free() en C (ou l'un des ensembles de possibilités en C++) et obtenir à peu près le même effet pratique. Cela a l'avantage de mieux s'adapter aux plus petites tailles de pile.

Cependant j'ai vu [1] un legit (si hacky!) L'utilisation de celui-ci: pour détecter un débordement de pile potentiel sur Windows; si l'allocation (de la quantité d'espace de slops que vous vouliez accéder) a échoué, vous étiez sorti mais vous aviez assez de place pour récupérer gracieusement. Il a été enveloppé dans __try/__except afin qu'il ne tombe pas en panne, et nécessite des astuces de l'assembleur supplémentaires pour éviter les problèmes induits par gcc. Comme je l'ai dit, un hack.Mais un intelligent qui est la seule utilisation valide pour alloca() que j'ai jamais vu.

Mais ne faites pas cela. Mieux vaut écrire le code pour ne pas avoir besoin de tels jeux.


[1] Il était en Tcl 8.4 (et versions antérieures éventuellement de Tcl). Il a été supprimé dans les versions ultérieures. Les versions ultérieures l'ont enlevé parce que c'était finicky, très délicat et profondément troublant. 8.6 utilise une implémentation sans pile du moteur d'exécution au lieu de ce genre de funkiness.

+0

FWIW: sous Windows, il y a généralement une page de garde à la fin de la pile, utilisée pour la développer dynamiquement. Une fois la limite de la pile atteinte et cette page de garde atteinte, vous obtenez l'exception - mais juste une fois. À moins qu'ils ne réinitialisent la page de garde après avoir détecté la fin de la pile, cette astuce ne fonctionnerait qu'une fois ... La prochaine fois, le système mettrait immédiatement fin au programme. – Shog9

+0

@Shog: Intéressant, bien que quelque chose dont nous n'avons plus besoin; nous avons changé la façon dont notre moteur d'implémentation fonctionne pour ne plus avoir besoin d'une pile C profonde. :-) J'ai juste pensé que ce serait intéressant pour les gens comme utilisation pour alloca qui ne peut pas être dupliquée du tout par malloc. –

+0

Je suis d'accord - merci de partager! – Shog9

0

L'utilisation alloca()peut raisonnable lorsque vous ne pouvez pas utiliser malloc() (ou new en C++, ou d'une autre allocateur de mémoire) de manière fiable, ou pas du tout, mais vous pouvez supposer qu'il ya plus d'espace disponible sur votre pile - à savoir, quand tu ne peux vraiment rien faire d'autre.

Par exemple, dans glibc « s segfault.c, nous avons:

/* This function is called when a segmentation fault is caught. The system 
    is in an unstable state now. This means especially that malloc() might 
    not work anymore. */ 
static void 
catch_segfault (int signal, SIGCONTEXT ctx) 
{ 
    void **arr; 

    /* ... */ 

    /* Get the backtrace. */ 
    arr = alloca (256 * sizeof (void *)); 

    /* ... */ 
} 
Questions connexes