IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Operateur "new" renvoi NULL


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5
    Points : 1
    Points
    1
    Par défaut Operateur "new" renvoi NULL
    Bonjour,
    Je cherche la raison pour laquelle l'operateur new me renvoie l'adresse NULL lors de l'allocation d'un tableau.

    Extrait du code ou le problème se produit :
    void Mdct::InverseTransform(float *In,float *Out)
    {
    float *Real;
    float *Imag;

    Real=new float[Size];

    }
    Au bout d'un certain nombre de création d'objet Mdct, et d'appel à cette fonction InverseTransform(), une erreur apparaît et j'ai pu voir grâce au debugger que l'adresse de mon pointeur "Real" est à zéro juste après le "new", size étant bien égal a une valeur correcte (1024 en l'occurrence) et ma mémoire n'étant pas saturée.

    Je pense bien sûr que le problème ne vient pas de cet extrait de code, mais comme je ne connais aucune cause possible au renvoi de l'adresse NULL par un "new", toute idée serait la bienvenue.

    Merci d'avance pour vos réponses.

  2. #2
    Expert éminent
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Points : 8 339
    Points
    8 339
    Par défaut
    il semble impossible que new renvoye NULL puisque s'il échoue, il est censé lever une exception bad_alloc, tu es sûr d'avoir bien effectué l'interogation sur la valeur de Real après l'affectation, et non après le retour de new (ce sont deux opérations différentes, et il est possible que ton débuggueur s'arrète entre les deux, ça m'est déjà arrivé...)
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag (en bas)

  3. #3
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Certrains vieux compilos non conformes (Visual C++ 6) renvoient NULL lorsque new échoue.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Si je me souviens bien, ils étaient conformes avant que les normes ne changent...

    Et Franchement, "C'était mieux avant". Mais bon, ce doit être mon esprit en C qui me dit ça...
    Il faut dire que personne n'aimerait que malloc() fasse une segfault au lieu de retourner NULL...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre confirmé
    Avatar de NewbiZ
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2002
    Messages
    184
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2002
    Messages : 184
    Points : 563
    Points
    563
    Par défaut
    Je dis peut être une bêtise mais new ne renvoie pas NULL quand il n'y a plus assez de mémoire ?

  6. #6
    Expert éminent
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Points : 8 339
    Points
    8 339
    Par défaut
    Citation Envoyé par Médinoc
    Il faut dire que personne n'aimerait que malloc() fasse une segfault au lieu de retourner NULL...
    new ne fait pas de segfault, il lève une exception bad_alloc (mm en cas de saturation de la mémoire, et Demerzel_01 a précisé que sa RAM n'était pas saturée)... je vois pas où est le problème, et perso, je préfère l'exception, ça évite justement les segfault
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag (en bas)

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Médinoc
    Si je me souviens bien, ils étaient conformes avant que les normes ne changent...

    Et Franchement, "C'était mieux avant". Mais bon, ce doit être mon esprit en C qui me dit ça...
    Un new qui retourne NULL en cas d'échec, ça veut dire qu'il faut tester chaque allocation. Un new qui lance une exception, ça veut dire qu'avec un handler global unique au programme, on peut gérer proprement et sans rien oublier tous les cas d'allocation posant problème dans les cas classiques (échec -> message et arrêt propre du programme).

    Je ne vois aucun avantage en l'occurence à un new qui ne lancerait pas d'exception, mais de toute façon, si c'est ce que tu veux, je t'invite à utiliser systèmatiquement T* t = new (nothrow) T;
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Hum. Quand je ne peux pas acquérir la mémoire nécessaire à mes opérations, je ne continue pas avec le traitement en cours. Je l'avorte. Et pour ça, les exceptions sont là. Alors entre tester moi-même pour lever l'exception et la regarder se lever toute seule ...
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    C'est vrai, j'ai un peu de mal avec les exceptions.
    Dépuis Java qui en lance une pour un oui ou pour un non, j'ai appris à les haïr.
    Mais je reconnais que les exceptions peuvent parfois s'avérer quasiment-indispensables, quand on fait des initialisations dans un constructeur.

    Quand au renvoi de NULL en cas d'échec, en habitué du C il ne me gênait pas. Mais Visual (je ne sais plus quelle(s) version(s)) me faisait un warning bizarre avec nothrow...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Laurent Gomila
    Certrains vieux compilos non conformes (Visual C++ 6) renvoient NULL lorsque new échoue.
    j'utilise visual.net
    J'ai tenté de lancer devpartner en mode "error detection" pour voir si celui ci me detectait une erreur lors de l'execution du code.... mais non. De plus, executer le code avec devpartner fait que celui-ci ne plante plus.

  11. #11
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    On peut avoir une idee de la valeur de Size?
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  12. #12
    Expert éminent
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Points : 8 339
    Points
    8 339
    Par défaut
    Dans son premier post :
    Citation Envoyé par Demerzel_01
    [...]size étant bien égal a une valeur correcte (1024 en l'occurrence)[...]
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag (en bas)

  13. #13
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    En simplifiant mon code a l'extreme il apparait une erreur de "stack overflow", cela pourrait il expliquer mon probleme ?

    Sinon mon code effectue la tache suivante :
    Je parcours un arbre de maniere recursive :
    un noeud de l'arbre verifie s'il a un descendant, si ce n'est pas le cas il crée un certain nombre de descendant du rang +1 de l'arbre et leur effectue un traitement visant a éliminer certaines branches de l'arbre, et si c'est cas il va pointer sur le noeud suivant afin d'effectuer la meme procedure.

    exemple du code utilisé(si ca peut aider a la comprehension):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    void	Branch::Feed(float *signal)
    {	
    	int n;
     
    	if(dead) return ;
    	if(Next)
    	{	
    		for(n=0;n<2;n++)
    			Next[n].Feed(signal);
    	}
    	else
    	{
    		Next = new Branch[2];
     
    	             Next[0].Init(this,0);
    	             Next[1].Init(this,1);
     
    		for(n=0;n<2;n++)
    			Next[n].Result(signal);
    	}
     
                 SimplifyTree();
    }
    Comme je le disais, je ne sature pas ma RAM, mais y a t il une limite "physique" a ce genre d'utilisation de recursion ? la je bloque a environ 3000 etages de mon arbre.

  14. #14
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Les variables locales des fonctions sont empilés sur la pile, et ne sont libérés qu'à la fin de la fonction. Le problème avec la récursion c'est que tant que tu n'as pas atteint la fin de la récursion, rien n'est libéré. Et la pile a une taille assez limitée.

    Essaye de déclarer tes variables locales ailleurs, ou mieux : remanier ton algo pour éviter ce genre de récursion.

  15. #15
    Membre habitué Avatar de harsh
    Inscrit en
    Février 2005
    Messages
    229
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 229
    Points : 193
    Points
    193
    Par défaut
    De toute maniere, j'ai deja fait tourner des softs qui prenait plus de memoire que de RAM presentent et je n'ai pas eu de stack overflow, je presume donc que Windows ecrit alors sur les disques (remarquez, le prog tournait mieux que je ne l'aurais pensé).

    EDIT: pourquoi la pile a t elle une taille limite???

    re-EDIT: je fais souvent tourner des prog tres/trop gourmand de traitement d'images et je n'ai jamais atteint une quelconque limite
    Avant de poser une question, lire la Avant de répondre, lire la question

  16. #16
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Si je me souviens bien, ils étaient conformes avant que les normes ne changent...
    MSVC6 est antécédant à la première norme de C++, issue en 1998.
    Boost ftw

  17. #17
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Je viens de voir tout plein de topics relatifs a la récursivité et/ou dépassement de pile, je vais donc allez potasser cela.

    Ceci dit, cela peut il expliquer mon problème initial ? Sur la version "lourde" de mon code, je ne voyait pas ce "stack overflow". En release, je me faisais ejecter du programme sans qu'il soit fini et sans message d'erreur et en debug je voyais apparaitre un new me renvoyant NULL .....

  18. #18
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    pourquoi la pile a t elle une taille limite???
    La pile étant faite pour recevoir les variables locales et les paramètres de fonction, elle peut être accédée très rapidement mais de ce fait doit être limitée. Comme tu le sais, en informatique, accés plus rapide rime avec taille plus faible.

    je fais souvent tourner des prog tres/trop gourmand de traitement d'images et je n'ai jamais atteint une quelconque limite
    Très certainement parce que tu utilises le free-store (ou tas) (l'espace mémoire utilisé par new).
    Pour faire péter la pile il n'y a que deux moyens : variable locale trop grosse (tableau de 50 000 éléments par exemple), ou récursivité trop lourde. Donc ce n'est pas étonnant que tu ne sois jamais tombé sur le problème.

    Ceci dit, cela peut il expliquer mon problème initial ? Sur la version "lourde" de mon code, je ne voyait pas ce "stack overflow". En release, je me faisais ejecter du programme sans qu'il soit fini et sans message d'erreur et en debug je voyais apparaitre un new me renvoyant NULL .....
    Comme je te l'ai dit, new manipule le free-store, donc aucun rapport avec la pile a priori.

  19. #19
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    j'ai juste augmenté la taille de ma pile et mon code a l'air de s'executer sans problème et jusqu'au bout. cette histoire de new restera donc un mystère

    Merci pour vos réponses en tout cas

  20. #20
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Laurent Gomila
    La pile étant faite pour recevoir les variables locales et les paramètres de fonction, elle peut être accédée très rapidement mais de ce fait doit être limitée. Comme tu le sais, en informatique, accés plus rapide rime avec taille plus faible.
    La pile est une zone mémoire comme une autre.

    Je vois deux raisons de limiter la taille de la pile sur des OS un espace mémoire par process:
    - certains peuvent réserver directement la mémoire pour la pile maximale (en mémoire ou en place dans le swap, ça revient au même), donc allouer trop de pile, c'est gaspiller une ressource.
    - on ne sait en pratique avoir au maximum 2 zones de tailles dynamiques (elles sont aux extrémités d'un espace partagé et grandissent l'une vers l'autre), or on en a en pratique plus le tas, les piles et l'espace pour les fichiers mappés en mémoire (dont les bibliothèques dynamiques). Des ceux-ci, les piles sont ceux qui peuvent le plus raisonnablement être contraints (et en plus, il y en a un nombre variable: autant qu'il y a de threads).

    A noter que même en travaillant pas mal avec des algo récursifs sur des graphes relativement gros (centaines de milliers de noeuds), je n'ai jamais eu de problème de dépassement de pile que quand j'avais un problème de fond -- "grosses" variables locales pouvant être partagées entre les appels récursifs, profondeur de pile proportionnelle à la taille des données quand il est possible de se limiter au logarithme de celle-ci... Sur le genre d'algo que j'ai programmés et avec le genre de graphes que nous traitons, une profondeur de 3000 serait typique de ce dernier problème.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

Discussions similaires

  1. Double quote qui viennent de nulle part
    Par mioux dans le forum Coldfusion
    Réponses: 4
    Dernier message: 26/04/2007, 13h42
  2. [JDBC]Un new qui renvoie null...
    Par Ditch dans le forum JDBC
    Réponses: 4
    Dernier message: 03/01/2005, 13h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo