Sans utiliser la récursivité, comment une exception de débordement de pile peut-elle être levée? Déclarer une matrice ENORMOUS comme variable locale.Sans utiliser la récursivité, comment une exception de dépassement de pile peut-elle être levée?
Répondre
Si vous appelez des méthodes assez, un débordement de pile peut se produire à tout moment. Bien que, si vous obtenez des erreurs de débordement de pile sans utiliser la récursivité, vous pouvez vouloir repenser comment vous faites des choses. C'est tellement simple avec la récursion car dans une boucle infinie, vous appelez une tonne de méthodes.
La plupart des compilateurs ne compileront simplement pas ceci. Ce n'est pas un débordement de pile. –
@Chris - Ne le compilera-t-il pas? Je pensais que la taille maximale de la pile était définie par l'éditeur de liens et non connue du compilateur. – ChrisW
le compilateur ne peut pas l'attraper, sauf si le compilateur est capable d'analyser le code pour l'utilisation de la pile d'exécution projetée, ce qui pourrait être extrêmement délicat. – JustJeff
Chaque appel de méthode qui n'a pas encore retourné consomme un peu d'espace de pile. (Les méthodes avec plus de variables locales consomment plus d'espace.) Une pile d'appels très profonde peut entraîner un débordement de pile.
Notez que sur les systèmes à mémoire limitée (appareils mobiles et autres) vous n'avez pas beaucoup d'espace de pile et courrez plus tôt.
J'ai travaillé sur un projet de console où nos processus avaient des piles de 32K. Dans l'une des routines, il y avait deux tableaux 16K. Bien que l'utilisation des tableaux soit exclusive et qu'ils n'aient pas la même portée, le compilateur a toujours alloué 32 Ko d'espace de pile et a débordé notre pile (théoriquement, un compilateur plus intelligent n'aurait réservé que 16 Ko). Je les ai changés à alloc/free pour résoudre le problème. – Adisak
Comme personne d'autre n'a mentionné:
throw new System.StackOverflowException();
Vous pouvez le faire lors du test ou de faire d'injection de faute.
Excellent - en supposant que vous utilisez .NET =) –
Si vous parlez C++ avec une bibliothèque standard raisonnable, je l'image que cela fonctionnerait:
while (true) {
alloca(1024 * 1024); // arbitrary - 1M per iteration.
}
Détails sur alloca.
Est-ce une exception stackoverflow ou out of memory? – Juliet
@juliet: La fonction alloca() alloue de l'espace dans le cadre de la pile de l'appelant. – pierrotlefou
Cela ne devrait pas déclencher une exception si alloca() est correctement implémentée. L'appel alloca() est censé renvoyer NULL s'il n'y a pas assez d'espace de pile plutôt que de lancer une exception. Ce qui devrait arriver, c'est qu'après avoir épuisé l'espace de la pile, votre code sera bloqué dans une boucle infinie d'appels alloca() retournant des valeurs NULL. – Adisak
Réponse courte: si vous avez un objet qui appelle un objet interne, vous augmentez la trace de la pile par 1. Donc, si vous avez 1000s d'objets imbriqués l'un dans l'autre, chacun appelant son objet interne, par la suite vous obtiendrez un débordement de pile.
est ici une démonstration de la façon de générer des nombres premiers en utilisant itérateurs imbriqués:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
IEnumerator<int> primes = p.AllPrimes().GetEnumerator();
int numberOfPrimes = 1000;
for (int i = 0; i <= numberOfPrimes; i++)
{
primes.MoveNext();
if (i % 1000 == 0)
{
Console.WriteLine(primes.Current);
}
}
Console.ReadKey(true);
}
IEnumerable<int> FilterDivisors(IEnumerator<int> seq, int num)
{
while (true)
{
int current = seq.Current;
if (current % num != 0)
{
yield return current;
}
seq.MoveNext();
}
}
IEnumerable<int> AllIntegers()
{
int i = 2;
while (true)
{
yield return i++;
}
}
IEnumerable<int> AllPrimes()
{
IEnumerator<int> nums = AllIntegers().GetEnumerator();
while (true)
{
nums.MoveNext();
int prime = nums.Current;
yield return prime;
// nested iterator makes a big boom
nums = FilterDivisors(nums, prime).GetEnumerator();
}
}
}
}
Il n'y a pas récursion, mais le programme lancera une exception de débordement de pile après environ 150 000 nombres premiers.
code ncie, me rappelle de l'évolution du programmeur Haskell :) (tonne de code contre oneliner - programmation d'un factoriel) –
Ce qui suit s'applique à Windows, mais la plupart des systèmes d'exploitation implémentent cela de la même manière.
La réponse courte est: si vous touchez la dernière page de garde, il va jeter.
Une exception de type EXCEPTION_STACK_OVERFLOW (C00000FD) est déclenchée lorsque votre application touche la dernière page de la pile, marquée d'un indicateur de protection PAGE_GUARD et qu'il n'y a pas de place pour développer la pile (valider une page supplémentaire), voir How to trap stack overflow in a Visual C++ application.
Le cas typique lorsque cela se produit est lorsque la pile a grandi à la suite de nombreuses fonctions sur la pile (c'est-à-dire hors récursivité), en raison de moins de cadres mais de très grandes tailles (fonctions avec un très grand objet local) ou en attribuant explicitement à partir de la pile avec _alloca
.
Une autre façon de provoquer l'exception est de simplement toucher intentionnellement la page de garde, par exemple. en déréférençant un pointeur qui pointe dans cette page. Cela peut arriver en raison d'un bug d'initialisation variable.
débordements de pile peuvent se produire sur les chemins d'exécution valides si l'entrée provoque un niveau d'imbrication très profonde.Par exemple voir Stack overflow occurs when you run a query that contains a large number of arguments inside an IN or a NOT IN clause in SQL Server.
meilleure façon de faire un StackOverflowException est le suivant:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
SomeClass instance = new SomeClass();
string name = instance.Name;
}
}
public class SomeClass
{
public string Name
{
get
{
return Name;
}
}
}
}
En fait, c'est la deuxième façon la plus simple après avoir levé l'exception :) –
La question spécifiquement exclu récursion. – meriton
Vous avez raison, mon erreur. –
int main()
{
//something on the stack
int foo = 0;
for (
//pointer to an address on the stack
int* p = &foo;
//forever
;
//ever lower on the stack (assuming that the stack grows downwards)
--p)
{
//write to the stack
*p = 42;
}
}
- 1. Java - Une exception doit être levée, mais comment?
- 2. (SHLWAPI.DLL): 0xC00000FD: dépassement de pile
- 3. Ocaml Exception "Mémoire insuffisante"; Le mode verbeux dit "Dépassement de pile dans la comparaison structurelle"
- 4. Dépassement de pile sur IIS 6.0
- 5. "Dépassement de pile à la ligne: 0" sur Internet Explorer
- 6. Dépassement de pile après 15 récursions avec la fonction de classe Javascript
- 7. Dépassement de pile de la DLL native appelée à partir de l'application gérée
- 8. Pourquoi une exception ClassCastException est-elle levée uniquement lorsque vous accédez à la valeur de retour?
- 9. Comment localiser une exception particulière dans une pile d'exception
- 10. Quelles sont les causes possibles d'un dépassement de pile?
- 11. Dépassement de la limite de la mémoire Wordpress dépassée, SANS modification de la limite du serveur
- 12. Comment utiliser le théorème Master pour décrire la récursivité?
- 13. Quelle exception doit être levée lorsqu'une requête ADO.NET ne peut pas récupérer les données demandées?
- 14. Éviter la récursivité
- 15. Exception levée lorsque l'ordre de déclaration des ressources a changé
- 16. Masquage de la pile pour une exception renvoyée par une méthode web asp.net?
- 17. Puis-je utiliser Collections.EMPTY_LIST sans une exception UncheckedException?
- 18. Débordement de pile C#
- 19. Comment obtenir la pile de pile dans un appareil mobile?
- 20. Dépassement de pile lors du remplacement de 'avec' 'dans VB 6.0
- 21. Existe-t-il un moyen de vider une trace de pile sans lancer une exception dans Java?
- 22. ORA-01426: exception de dépassement numérique lors de l'exécution de la procédure stockée
- 23. Pourquoi une exception est-elle levée depuis Spring.NET lors de l'appel de ContextRegistry.GetContext()?
- 24. Stack déborde de la récursivité profonde dans Java?
- 25. Python sans pile et multicores?
- 26. Pourquoi une violation d'accès pour cout et dépassement de pile pour printf
- 27. Dépassement de pile lors de l'ouverture du menu avec ApplicationCommands en C#
- 28. Vulnérabilité avec cryptage des informations de cookie pour l'authentification (podcast de dépassement de pile)
- 29. Comment obtenir une trace de la pile de FastMM
- 30. programme d'interruption dans le débogueur lorsque C++ exception est levée
Désolé pour le corps de question répétitive, mais je ne pouvais penser à rien qui vaille à ajouter. – JaredCacurak
C'est bon. Je me suis souvent retrouvé dans la même situation :) – pierrotlefou
Vous pouvez toujours mettre nt (pas de texte) dans le corps. Cela a toujours fonctionné dans les jours de BBS. –