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 :

verifier si vecteur de pointeur est vide


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 5
    Points : 7
    Points
    7
    Par défaut verifier si vecteur de pointeur est vide
    Bonjour,

    j'utilise un tableau de pointeur qui represente une table de hachage (chaque case pointe sur une liste). La fonction de hachage prend une chaîne de caractères et me retourne un entier représente un indice dans le tableau.

    Avant d'insérer dans le tableau, je dois d'abord vérifer si la case est vide !
    Donc ma question est, quand je déclare ce tableau de pointeurs, par quelle valeurs les cases seront initialisées ? par NULL ou autre valeurs ?
    Si non pas par NULL,, comment je vérifie si la case est libre (Ps: sans que je l'initialise moi meme).
    ma structure :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef struct {char *c, struct ts *svt}ts;
    ts* tab[100];

    merci.

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    En C, si tu ne fais rien pour initialiser, rien n'est fait par le langage.

    La seule subtilité, c'est l'initialisation partielle d'un tableau.
    C'est à dire, que la déclaration int* tab[16] = {NULL}; définit la première case à NULL et les 15 suivantes à 0.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Bonjour et bienvenue :

    Réponse courte : elles ne seront pas initialisées du tout ! Il faudra donc prendre le soin de le faire au moment où tu déclares ton tableau.

    Réponse un peu plus longue : l'initialisation de tes variables est indépendante du modèle de structures de données que tu utilises. La norme C stipule que les variables globales ou statiques doivent être initialisées à zéro par le programme compilé (principalement parce que comme elles sont persistantes, on ne peut pas savoir si c'est la première fois ou non qu'on les visite et il leur faut donc une valeur initiale déterminée à l'avance) et que tout ce qui est dynamique est laissé tel quel : la mémoire est simplement réservée pour ton usage personnel et elle t'est mise à disposition dans l'état dans lequel elle se trouve.

    C'est important parce l'utilisation de variables ou d'espace mémoire non initialisé est a priori un « comportement indéfini » mais dans certains cas, si tu appelles une fonction qui alloue de la mémoire, que tu en sors, et que tu entres à nouveau dans la même fonction juste après, il est probable que tu ré-alloues exactement la même plage et que les valeurs qui s'y trouvent, bien qu'obsolètes, paraissent cohérentes et que ta fonction renvoie des résultats en apparence légitimes mais malgré tout complètement faux.

    Cela conduit à des bugs très difficiles à déceler et encore plus à corriger. D'où l'intérêt d'adopter une bonne méthodologie, de se pencher sur ces cas de figure dès le départ comme tu le fais, et de s'aider de logiciels de profilage et d'analyse mémoire comme valgrind.

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 5
    Points : 7
    Points
    7
    Par défaut
    et donc comment je peux verifier si j'ai déja remplis une case auparavant ou pas ?
    faut-il que je l'initialiser par NULL pour le verifier ?? y'a pas d'autres moyens ?

  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Un tableau est toujours rempli, mais par défaut, de "bruit".

    A toi de faire en sorte de savoir si tu peux te servir des pointeurs de ton tableau.
    Il n'y a que deux solutions classiques:
    • Mettre des NULL et vérifier chaque pointeur avant de s'en servir, c'est à dire faire comme avec n'importe quel pointeur.
    • Avoir le nombre de cases actives, et n'utiliser que les premières. (façon "buffer")


    Dans le cas d'une table de hashage, seule la première est utilisable: ton tableau est plein, mais de listes qui sont vides.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Pour compléter ce que dis très bien ternel, et pour faire référence à ceci :

    Citation Envoyé par kami08 Voir le message
    faut-il que je l'initialiser par NULL pour le verifier ?? y'a pas d'autres moyens ?
    C'est justement la justification de ce point dont il faut débattre : c'est exactement la même chose dans tous les autres langages sauf que, comme tu le précises, on s'attend justement à ce que le framework que l'on utilise nous les ait justement mises à zéro pour nous, implicitement. Cela implique donc à la fois d'avoir convenu, même tacitement, d'un état initial (ici NULL) et qu'une routine exécutée automatiquement avant l'exécution de notre propre programme ait fait le ménage pour nous.

    Pourquoi est-ce que ce n'est pas le cas ici ? Parce qu'on travaille justement au niveau de la routine en question. Routine qui, dans les autres langages, a de fortes chances d'être elle-même écrite en C. Et également parce que comme on l'a expliqué au dessus, non seulement la valeur initiale doit être clairement définie (ce n'est pas forcément NULL ni zéro), mais également parce que cela a un coût ! Même en C, cela reste encore un peu abstrait, surtout sur des machines modernes, mais quand on travaille en assembleur et sur des microcontrôleurs à la cadence limitée, ça prend tout son sens ! De fait, il est déraisonnable d'imposer dans la norme des traitements coûteux à la fois en mémoire (code machine) et en temps d'exécution sur chacune des variables si cela est potentiellement inutile. Et ça l'est puisque la plupart du temps, c'est le programmeur qui commence par affecter une valeur à sa variable, soit depuis une constante, soit en évaluant une expression (qui elle même peut être un paramètre extérieur, par exemple).

    Maintenant, si ça te saoule d'écrire une boucle pour initialiser le moindre tableau (et on peut le comprendre), soit tu utilises memset() pour mettre une plage à zéro si celle-ci est déjà réservée (par exemple avec malloc()… et encore : pour cela, il existe calloc()), soit tu utilises la notation ensembliste pointée du doigt par ternel : « { } ». Dans le cas présent, tu n'aurais besoin que de rajouter :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef struct {char *c, struct ts *svt}ts;
    ts* tab[100] = { NULL };

    … à ton code. À noter tout de même qu'en C, NULL n'est pas un mot-clé réservé du langage mais une macro définie avec #define dans <stddef.h> (que l'on ne voit jamais parce que ce fichier est généralement inclus par les autres fichiers standard comme <stdio.h>) et que c'est une valeur réservée choisie précisément pour représenter l'absence de valeur, comme dans les bases de données. Seulement, je ne connais aucune plateforme qui ait l'idée saugrenue de définir cette valeur autrement qu'à zéro. Si ça te tracasse, tu peux utiliser #if, #ifder, #error, et assert() en début de programme pour interrompre la compilation ou l'exécution de ton programme sur toute plateforme sur laquelle ce serait quand même le cas, mais tu n'en es pas là pour le moment.

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ternel Voir le message
    Un tableau est toujours rempli, mais par défaut, de "bruit".
    Ce n'est vrai que pour les variables qui ont une "automatic storage duration". Dans le cas contraire, elles contiennent des 0 (ou des NULL ou équivalent).

    Pour plus de détails https://gradot.wordpress.com/2012/09...ructures-en-c/

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par kami08 Voir le message
    et donc comment je peux verifier si j'ai déja remplis une case auparavant ou pas ?
    faut-il que je l'initialiser par NULL pour le verifier ?? y'a pas d'autres moyens ?
    Bonjour

    Hé oui, il n'y a pas d'autre moyen. C'est seulement en remplissant toi-même les cases de ton tableau que tu pourras savoir avec certitude que tu les as remplies.
    Et NULL (pour un pointeur) parce que c'est la seule valeur licite qui indique "pointeur créé mais pas encore utilisable parce que sans mémoire".
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut
    Bonjour,

    Avant l'utilisation de tableau, pour les initialiser, j'utilise la fonction memset.
    Dans ton cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <string.h>
    typedef struct {char *c, struct ts *svt}ts;
    ts* tab[100];
     
    /* Dans le main ou fonction d'init */
    memset(&tab, NULL, sizeof(tab));
     
    /* Test d'une cellule non allouée */
    if(tab[i] == NULL {
        /* code */
    }
    Après il t'es possible de faire une comparaison avec NULL.

    Bonne continuation
    - Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
    - Travailler dur n'a jamais tué personne, mais pourquoi prendre le risque (Edgar Bergen)

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

Discussions similaires

  1. Verifier si le textarea est vide ou non
    Par marsupilami34 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 03/02/2009, 07h44
  2. [MySQL] Verifier si un champ est vide et on ne l'affiche pas
    Par cysedbs dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 12/12/2007, 16h31
  3. verifier si dataset est vide ou non
    Par ikouas dans le forum VB.NET
    Réponses: 2
    Dernier message: 02/05/2007, 21h24
  4. comment verifier si la cellule est vide
    Par k-eisti dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 25/04/2007, 13h40
  5. Verifier si un TMemo est vide ?
    Par Beauserge dans le forum Delphi
    Réponses: 2
    Dernier message: 01/11/2006, 11h43

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