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 :

Vérification d'une allocation statique


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2013
    Messages : 24
    Par défaut Vérification d'une allocation statique
    Bonjour,

    J'aimerais savoir comment vérifier que la création d'une variable s'est bien faite ?
    Je m'explique:

    J'ai remarqué avec un programme bateau que la stack était limité à 15 Mo.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main(void)
    {
        int a[3 000 000];
        a[0] = 0;
    }
    output-> segmentation fault
    Je présume que c'est modifiable mais là n'est pas la question.

    J'aimerais savoir comment je peux vérifier qu'un char tab[100] s'est bien créé. Je peux bien sûr allouer dynamiquement mais ça implique de libérer cette mémoire et on perd en performance.

    Merci d'avance

  2. #2
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Bonsoir,

    une allocation sur la pile se passe bien si tu n'as pas de segfault ok, c'est une réponse bateau, mais c'est exactement ça : si l'allocation échoue ton programme segfault et tu ne peux rien y faire, c'est un signal que tu ne peux intercepter.

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 484
    Par défaut
    Citation Envoyé par nsvir Voir le message
    J'aimerais savoir comment je peux vérifier qu'un char tab[100] s'est bien créé. Je peux bien sûr allouer dynamiquement mais ça implique de libérer cette mémoire et on perd en performance.
    Pour compléter ce que dit kwariz, non seulement il n'y a pas de « constructeur » comme dans d'autres langages de plus haut niveau mais cela ne fait pas non plus appel à un dispositif particulier : le pointeur de pile est simplement décrémenté pour laisser la place aux variables qui doivent s'y trouver et la taille comme l'emplacement des variables par rapport à l'état initial du pointeur (sauvegardé dans EBP sur IA32) est calculée à l'avance par le compilateur (sauf VLAs).

    En ce sens, le programme en lui-même est valide. Si ton système d'exploitation t'a alloué moins de place que tu n'en réserves dans la pile, un accès à ton tableau va taper en dehors de la zone allouée exactement de la même façon que lors d'un banal dépassement de tableau.

    Je présume que c'est modifiable mais là n'est pas la question.
    C'est surtout qu'il ne faut pas le faire : la règle en programmation est d'être aussi sobre que possible avec la pile. certaines personnes bannissent purement et simplement les passages par valeur d'arguments autres que des types natifs (idem pour la valeur de retour d'une fonction), et il existe même un flag spécial sur les compilateurs tels que GCC pour déclencher des warnings lorsque c'est le cas.

    Je trouve ça très excessif mais 15 Mo pour un tableau local, c'est l'extrême inverse.

    Citation Envoyé par kwariz Voir le message
    si l'allocation échoue ton programme segfault et tu ne peux rien y faire, c'est un signal que tu ne peux intercepter.
    Techniquement si et il existe même une bibliothèque mais chut ! On ne va pas se mettre à ouvrir la boîte de Pandore, et surtout pas à ce stade. ;-)

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2013
    Messages : 24
    Par défaut
    Merci pour vos réponses!

    les passages par valeur d'arguments autres que des types natifs
    Qu'entends tu par des types natifs ?

    la règle en programmation est d'être aussi sobre que possible avec la pile.
    J'en conclus qu'il faut utiliser le moins possible la pile ? Donc pas de récursivité ni de déclaration de tableau ou de structure ?

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 484
    Par défaut
    Citation Envoyé par nsvir Voir le message
    Qu'entends tu par des types natifs ?
    Les types prédéfinis du C (int, char, float, etc.) par opposition à ceux que tu définis toi-même soit en construisant des structures, soit en faisant des aliases avec typedef.

    J'en conclus qu'il faut utiliser le moins possible la pile ? Donc pas de récursivité ni de déclaration de tableau ou de structure ?
    Non, pas à ce point-là. Et ce serait vraiment dommage de se passer de récursivité. En outre, tu peux très bien utiliser la pile comme tu le sens si tu es sûr de rester dans les limites et que tu as vérifié à l'avance qu'immobiliser une certaine taille ne va provoquer aucun effet secondaire.

    Par contre, beaucoup de programmeurs débutants allouent directement des tableaux de taille invraisemblables directement dans la pile simplement parce que c'est plus simple que de faire un malloc() + free().

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2013
    Messages : 24
    Par défaut
    D'accord merci.

    Vue que tu parles de typedef. J'ai entendu dire que c'était pas anodin pour l'optimisation du programme de faire des typedefs.

    Je voulais donc savoir si c'était juste le compilo qui remplacait, (a la hauteur d'un define) ou si ça changeait l'execution du binaire.

  7. #7
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    C'est le compilo qui change les types et les vérifie du même coup... rien de changé à l'exécution.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  8. #8
    Membre émérite
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Par défaut
    Bonjour,

    Citation Envoyé par nsvir Voir le message
    [...] J'ai entendu dire que c'était pas anodin pour l'optimisation du programme de faire des typedefs.
    Ce que tu as entendu dire est faux ; les alias de type apportent simplement de l'information sémantique, à destination de ceux qui écrivent ou maintiennent le code. À priori, cela n'a pas d'influence directe sur la rapidité d'exécution (si c'est bien ce que tu entends par « optimisation du programme »).

    Citation Envoyé par nsvir Voir le message
    Je voulais donc savoir si c'était juste le compilo qui remplacait, (a la hauteur d'un define) ou si ça changeait l'execution du binaire.
    Comme dit plus haut, ça ne devrait rien changer à l'exécution du binaire (du moment que les types sous-jacents sous les mêmes, évidemment). En fait ça va même plus loin : toutes les informations de typage n'existent plus à l'exécution (disons, sur une implémentation typique du langage, sans parler des architectures dites « taguées », donc). Le compilateur est libre d'insérer dans le code machine généré quelques bouts de code permettant d'effectuer proprement les conversions, mais, comme dans la plupart des langages au typage statique, on ne se préoccupe plus de ces informations lors de l'exécution. C'est un gain en espace mémoire qui n'est pas négligeable.

    On notera que la directive #define provient du préprocesseur ; elle est donc gérée antérieurement à la compilation (au sens propre du terme). D'autre part, la portée syntaxique d'une définition de type avec une telle primitive est différente ; il faut bien comprendre que le préprocesseur n'est pas forcément fait pour faire des alias de type. Vulgairement, il faudrait le comprendre comme une boîte noire très bête qui ne fait que des copiés/collés. Ça pose notamment des problèmes quand on commence à toucher aux alias de pointeurs, et, d'un point de vue plus pratique, quand on veut gérer plus finement la portée de ses types (car on peut donner une portée au bloc avec typedef, ce qui est plus simple à gérer que des enchaînements de #define et #undef). C'est différent de l'analyse du compilateur, qui se fait, elle, plus en profondeur. Mais, ça, c'est une autre histoire.

    Bonne journée !
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  9. #9
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2013
    Messages : 24
    Par défaut
    Merci pour ta réponses très complete!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 18/01/2006, 15h17
  2. [Javascript] Vérification d'une date
    Par slyv dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 08/11/2005, 08h36
  3. Utiliser une bibliothèque statique
    Par djflex68 dans le forum MFC
    Réponses: 6
    Dernier message: 15/08/2005, 19h26
  4. Vérification d'une date
    Par MonsieurPaul dans le forum VB 6 et antérieur
    Réponses: 14
    Dernier message: 12/08/2005, 16h39
  5. Vérification d'une requête ...
    Par Kokito dans le forum Bases de données
    Réponses: 3
    Dernier message: 24/06/2004, 13h59

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