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 :

Demande d'éclaircissements dans l'utilisation de malloc() et de realloc().


Sujet :

C

  1. #1
    Rédacteur

    Avatar de naute
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2009
    Messages
    708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2009
    Messages : 708
    Par défaut Demande d'éclaircissements dans l'utilisation de malloc() et de realloc().
    Bonjour .

    J'ai besoin d'utiliser les techniques d'allocation dynamique de mémoire pour travailler sur des chaînes de caractères dans des programmes C. Mes connaissances en C étant très limitées, je fais des tests et je consulte les tutoriels traitant de ce sujet.
    Je butte actuellement sur deux problèmes :
    1. Le premier problème vient d'un fragment de code issu du tutoriel Description des mécanismes d'allocation dynamique de mémoire en langage C :
      Code C : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
       
      int * temp;
      temp = realloc (tabentier, 4 * sizeof(int) );
       
      if ( temp == NULL )
      {
           fprintf(stderr,"Reallocation impossible");
           free(tabentier);
           exit(EXIT_FAILURE);
      }
      else
      {
           tabentier = temp;
      }
      Si on libère le pointeur "tabentier" en cas de réallocation impossible, les données sur lesquelles il pointait deviennent inaccessibles. Le fait de passer par un pointeur temporaire pour protéger "tabentier" ne sert donc plus à rien. D'autre part, si l'allocation réussit, une fois que "tabentier" a pris la valeur "temp", que devient son ancienne adresse mémoire ?
    2. Le second problème concerne ce bout de code venant de mes tests :
      Code C : 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
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
       
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
       
      int main()
      {
        unsigned char *reception = NULL;  // Caractères ASCII de 0 à 255
        int taille = 50;
        int nbCar;
        reception = malloc(taille); // Allocation de la mémoire
        if (reception == NULL)
        {
          exit(0);
        }
        for (int i = 0; i < taille; i++)
        {
          reception[i] = NULL;
        }
        reception[taille -1] = '\0';
        printf("L'adresse mémoire est %d\n", reception);
        printf("sizeof(*reception) = %i\n", sizeof(*reception));
        printf("sizeof(reception) = %i\n", sizeof(reception));
        printf("Le contenu de \"réception\" est \"%d\"\n", *reception);
        printf("Saisissez une chaîne : ");
        scanf("%s", reception);
        nbCar = strlen(reception);
        reception[nbCar] = '\0';  //  Ajout du caractère de fin de chaîne
        printf("Vous avez saisi \"%s\"\n", reception);
        printf("La chaîne fait %d caractères\n", nbCar);
        for (int i = 0; i < nbCar; i++)
        {
          printf("Le caractère n° %d est : %c (ASCII %d)\n", i, reception[i], reception[i]);
        }
        free(reception);
        reception = NULL;
        return(0);
      }
      Si je saisi "Développez.com c'est cool !", voici ce que j'obtiens:
      Nom : Capture du 2020-03-09 16-00-13.png
Affichages : 363
Taille : 11,4 Ko
      Les deux points qui m'embêtent le plus sont :
      • pourquoi la chaîne est-elle coupée au niveau de l'espace ?
      • pourquoi le caractère accentué n'est-il pas reconnu quand j'affiche les caractères un par un alors qu'il l'est quand j'affiche la chaîne ?

      Pour info, le "é" de code ASCII 130 est toujours remplacé par les caractères de code ASCII 195 et 169, le "à" (133) sera remplacé par 195 et 160, le "ù" (151) par 195 et 185 etc.


    Les explications sont peut-être très simples mais moi je me gratte la tête .

    Si quelqu'un pouvait éclairer ma lanterne, ce serait super sympa.

    Amicalement,
    naute

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 750
    Par défaut
    Documentation de realloc en anglais
    C'est la façon que travaille la fonction realloc
    Si elle réussit à réallouer (ou allouer la première fois équivalent à 1 malloc) elle libère l'ancien emplacement et retourne l'adresse du nouvel emplacement. Sinon elle retourne NULL sans toucher à l'emplacement mémoire.
    Ici en cas d'erreur tu libères l'emplacement parce que tu quittes le programme.

    Documentation de scanf en anglais elle s'arrête dès le 1ier espace

    Et également, la table des caractères ASCII va de 0 à 127, et non 255 . Donc les caractères au delà ne sont pas de l'ASCII (soit du MBCS, soit de l'Unicode (UTF-8 ou UTF-16)). C'est pour cela qu'ils ne s'affichent pas bien.
    La console/ ligne de commandes sous Windows devient en 2020 Unicode, mais avant c'est du MBCS et donc il faut choisir le bon "codepage"


    Édit : D'ailleurs as-tu remarqué que dans la librairie standard C, les caractères sont de type char Cela veut dire que ton entier est signé (dépend de ton compilateur mais à 98% sûr) donc une plage de valeurs de [-127, 127]
    Ce qui n'est pas pratique lorsqu'on parse un fichier Unicode (UTF-8 ou UTF-16), qui lui, pour le coup, a des valeurs dans une plage [0, 255]

  3. #3
    Rédacteur

    Avatar de naute
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2009
    Messages
    708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2009
    Messages : 708
    Par défaut
    Merci pour tes réponses et les liens .

    Citation Envoyé par foetus Voir le message
    elle libère l'ancien emplacement
    J'étais passé à côté de ça. Donc OK pour realloc().

    Citation Envoyé par foetus Voir le message
    elle s'arrête dès le 1ier espace
    Alors comment on fait quand on traite une chaîne comportant des espaces, ce qui est assez fréquent ?

    Citation Envoyé par foetus Voir le message
    Et également, la table des caractères ASCII va de 0 à 127, et non 255 . Donc les caractères au delà ne sont pas de l'ASCII (soit du MBCS, soit de l'Unicode (UTF-8 ou UTF-16)).
    On entend pourtant assez souvent parler d'ASCII étendu, mais c'est vrai qu'à partir de 128, ce n'est plus standard.

    Citation Envoyé par foetus Voir le message
    C'est pour cela qu'ils ne s'affichent pas bien.
    Je suis d'accord mais dans ce cas, pourquoi l'affichage est bon avec %s et pas avec %c ? Ce n'est pas très cohérent.

    Citation Envoyé par foetus Voir le message
    D'ailleurs as-tu remarqué que dans la librairie standard C, les caractères sont de type char
    C'est la raison pour laquelle, naïvement, j'avais déclaré mon pointeur comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned char *reception = NULL;  // Caractères ASCII de 0 à 255
    Est-ce qu'on peut travailler en UTF-8 avec scanf() et printf() ?

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 811
    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 811
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par naute Voir le message
    Si on libère le pointeur "tabentier" en cas de réallocation impossible, les données sur lesquelles il pointait deviennent inaccessibles.
    Pas tout à fait. la zone existe toujours en mémoire. Simplement elle est libre pour qui en aura besoin.

    Citation Envoyé par naute Voir le message
    D'autre part, si l'allocation réussit, une fois que "tabentier" a pris la valeur "temp", que devient son ancienne adresse mémoire ?
    Dans la réallocation (qui n'a de sens que si on agrandit la zone initiale), soit la partie "en plus" peut se greffer à la zone déjà alloué et rien de visible ne se passe (la zone initiale faisait "n" maintenant elle fait "m" et c'est tout), soit il faut tout mettre ailleurs et dans ce cas, la zone initiale est alors recopiée ailleurs. Et dans ce cas, la zone initiale est alors libérée pour quelqu'un d'autre.

    En fait, pour bien comprendre malloc(), représente-toi la mémoire comme une immense suite de cases. malloc() c'est juste un truc qui en prend une presque au hasard et qui dit à l'OS "ok, donc maintenant depuis cette case jusqu'à n tout est à moi". Soit l'OS dit "ok" et malloc() te renvoie l'adresse de ladite case (et comme tu connais "n" vu que c'est toi qui l'a demandé t'as alors tout en main pour bien gérer ta zone) ; soit l'OS dit "je peux pas parce que je suis raide en ce moment" et malloc() te renvoie NULL et positionne la variable globale "errno" avec la cause du souci. Et si tu affiches la string renvoyée par strerror(errno) tu auras alors la cause donnée par l'OS.

    Citation Envoyé par naute Voir le message
    pourquoi la chaîne est-elle coupée au niveau de l'espace ?
    C'est le fonctionnement de scanf() qui utilise l'espace pour se repérer. Te faut passer par fgets() si tu veux tout récupérer.

    Citation Envoyé par naute Voir le message
    pourquoi le caractère accentué n'est-il pas reconnu quand j'affiche les caractères un par un alors qu'il l'est quand j'affiche la chaîne ?
    Souci d'encoding. En utf8 (qui est maintenant standard), un caractère accentué fait 2 octets. Le format "%s" sait le prendre en compte mais pas le "%c".

    Sinon quelques erreurs dans ton code
    1) reception[i]=NULL => NULL est une valeur de pointeur et reception[i] est un char. Même si à la base tout est nombre et qu'on peut parfaitement copier un pointeur NULL dans un char/int (cast implicite), vaut mieux écrire une valeur dédiée aux char/int => reception[i]='\0' ou reception[i]=0. Et dans ce cas, tu vois que reception[taille -1] = '\0' du dessous devient inutile. Et (si on élargit le débat), cette partie d'initialisation est en réalité totalement inutile vu que tu vas écraser la zone initialisée par ta saisie (enfin c'est ma façon de voir mais d'autres intervenant te diront qu'initialiser systémétiquement te protège contre un oubli).
    Mais si vraiment tu veux initialiser, tu peux alors utiliser memset() qui fait la boucle à ta place.
    2) tu n'as pas besoin de positionner le '\0' après la saisie. En effet, les fonctions de saisie de strings le mettent elles-même. D'autant plus que si tu le positionnes, ça veut dire que tu pars du principe qu'il n'y est pas. Mais s'il n'y est pas, tu n'as alors pas le droit d'utiliser des fonctions de lecture de string comme strlen() car ces fonctions utilisent justement le '\0' pour se repérer
    3) attention à sizeof() car pour un pointeur, même un pointeur alloué, il te renvoie quand-même la taille du pointeur (4 ou 8 octets suivant que tu es en 32b ou 64b).
    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]

  5. #5
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 750
    Par défaut
    Quelques réponses

    Citation Envoyé par naute Voir le message
    Est-ce qu'on peut travailler en UTF-8 avec scanf() et printf() ?
    Il faut passer par le type wchar_t et la bibliothèque wchar.h (<- documentation cplusplus en anglais) avec les fonctions wscanf et wprintf.


    Citation Envoyé par naute Voir le message
    Je suis d'accord mais dans ce cas, pourquoi l'affichage est bon avec %s et pas avec %c ?
    Simple parce que ton caractère est sur plusieurs octets. Donc il faut lire tous les octets pour afficher le caractère correctement (sous Linux - ta capture - est en UTF-8 il me semble )
    Édit : barbecued par @Sve@r


    Citation Envoyé par naute Voir le message
    Est-ce qu'on peut travailler en UTF-8 ?
    Par contre avec un fichier il n'y a pas de problème. avec les fonctions getc/ gets. Il faut caster en unsigned char et reconstitué les caractères si nécessaire.

  6. #6
    Rédacteur

    Avatar de naute
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2009
    Messages
    708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2009
    Messages : 708
    Par défaut
    Bonjour Sve@r .

    Citation Envoyé par Sve@r Voir le message
    Pas tout à fait. la zone existe toujours en mémoire. Simplement elle est libre pour qui en aura besoin.
    Je me suis mal exprimé : je voulais dire qu'elle était devenue inaccessible pour le programme. Cela dit, puisqu'on le quitte, ça n'a plus d'importance.

    Citation Envoyé par Sve@r Voir le message
    Dans la réallocation (qui n'a de sens que si on agrandit la zone initiale), soit la partie "en plus" peut se greffer à la zone déjà alloué et rien de visible ne se passe (la zone initiale faisait "n" maintenant elle fait "m" et c'est tout), soit il faut tout mettre ailleurs et dans ce cas, la zone initiale est alors recopiée ailleurs.
    Compris

    Citation Envoyé par Sve@r Voir le message
    Et dans ce cas, la zone initiale est alors libérée pour quelqu'un d'autre.
    Ça rejoint ce que disais foetus.

    Citation Envoyé par Sve@r Voir le message
    En fait, pour bien comprendre malloc(), représente-toi la mémoire comme une immense suite de cases
    .../...
    Et si tu affiches la string renvoyée par strerror(errno) tu auras alors la cause donnée par l'OS.
    OK. J'ai parfois une adresse mémoire négative : ça correspond à quoi ?

    Citation Envoyé par Sve@r Voir le message
    C'est le fonctionnement de scanf() qui utilise l'espace pour se repérer. Te faut passer par fgets() si tu veux tout récupérer.
    J'ai essayé avec :
    ça fonctionne mais gare aux débordements.
    Je ne vois pas comment utiliser fgets() dans mon cas (avec l'entrée standard).

    Citation Envoyé par Sve@r Voir le message
    Souci d'encoding. En utf8 (qui est maintenant standard), un caractère accentué fait 2 octets. Le format "%s" sait le prendre en compte mais pas le "%c".
    C'est tout à fait logique. J'aurai dû y penser .

    Citation Envoyé par Sve@r Voir le message
    Sinon quelques erreurs dans ton code...
    Je vais modifier mon code en tenant compte de tes remarques.

    Citation Envoyé par Sve@r Voir le message
    3) attention à sizeof() car pour un pointeur, même un pointeur alloué, il te renvoie quand-même la taille du pointeur (4 ou 8 octets suivant que tu es en 32b ou 64b).
    Là je ne pige pas trop. Est-ce que ça veut dire que quand tu demandes une allocation mémoire pour un char, du genre :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    reception = malloc(1 * sizeof(char));
    donc 1 octet, on te réserve 8 octets ?


    @foetus

    Citation Envoyé par foetus Voir le message
    Simple parce que ton caractère est sur plusieurs octets. Donc il faut lire tous les octets pour afficher le caractère correctement (sous Linux - ta capture - est en UTF-8 il me semble )
    Trop tard .

    Citation Envoyé par foetus Voir le message
    Par contre avec un fichier il n'y a pas de problème. avec les fonctions getc/ gets. Il faut caster en unsigned char et reconstitué les caractères si nécessaire.
    gets() est vu plus haut, quant à getc(), il pose le même problème que fgets(). Je ne lis pas depuis un fichier.
    Je vais également aller voir du côté de getchar().

    En tous cas, merci pour vos conseils. Il me font bien avancer.

    À bientôt,
    naute

  7. #7
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 750
    Par défaut
    Citation Envoyé par naute Voir le message
    OK. J'ai parfois une adresse mémoire négative : ça correspond à quoi ?
    Au format printf (<- lien cplusplus en anglais avec tous les formats)

    %d c'est pour 1 entier signé, %u pour 1 entier non signé et surtout %p pour une adresse mémoire.


    Citation Envoyé par naute Voir le message
    Là je ne pige pas trop. Est-ce que ça veut dire que quand tu demandes une allocation mémoire pour un char
    Tu n'as pas compris
    Le nombre d’adresses mémoire dépend du nombre de bits du processeur. Un processeur X bits peut allouer au plus 2^(X / 8) octets, donc une plage d’adresses [0, 2^(X / 8) - 1].
    Et donc lorsque tu prends la taille d'un pointeur avec sizeof, c'est toujours soit 4 octets (pour un processeur 32 bits) soit 8 octets (pour un processeur 64 bits, mais la mémoire est limitée à 48 il me semble ).

    Après, cela va dépendre de ton système d'exploitation du nombre d'octets qu'il va allouer pour tel ou tel malloc (et effectivement il peut y avoir éventuellement de l'alignement mémoire, lien wiki en français)

  8. #8
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 175
    Par défaut
    gets() est vu plus haut, quant à getc(), il pose le même problème que fgets(). Je ne lis pas depuis un fichier.
    Sous Unix, tout est fichier. Tu peux lire la console comme un fichier dont le handle se nomme stdin.

    gets peut être vu comme un équivalent de fgets sur le fichier stdin mais sans contrôle de débordement.
    gets lira la chaine jusqu'à un retour chariot (ou EOF), il ne s'occupera pas de la taille du buffer. fgets lira jusqu'à un retour chariot, ou le nombre max passé en paramètre. fgets stocke le retour chariot dans la chaine contrairement à gets.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  9. #9
    Rédacteur

    Avatar de naute
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2009
    Messages
    708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2009
    Messages : 708
    Par défaut
    Bonjour .

    @foetus
    Citation Envoyé par foetus Voir le message
    Au format .../... et surtout %p pour une adresse mémoire.
    Effectivement, là il n'y a plus d'ambiguïté.

    Citation Envoyé par foetus Voir le message
    Tu n'as pas compris
    Je sais bien . C'est pour ça que je suis ici . Mais j'me soigne .
    Ah ! le bon vieux temps du mode réel et des segments de 64 K .

    @chrtophe
    Citation Envoyé par chrtophe Voir le message
    Sous Unix, tout est fichier. Tu peux lire la console comme un fichier dont le handle se nomme stdin.
    Très juste ! Effectivement, comme ça, fgets() fonctionne sans problème .

    Avec les bonnes explications, on finit par y arriver .

    à vous deux,
    amicalement,
    naute

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 811
    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 811
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par naute Voir le message
    Cela dit, puisqu'on le quitte, ça n'a plus d'importance.
    Exactement. Très bonne philosophie. Quand on ferme/quitte/libère un truc, faut pas se préoccuper de ce que devient le truc puisqu'on ne s'en sert plus.

    Citation Envoyé par naute Voir le message
    OK. J'ai parfois une adresse mémoire négative : ça correspond à quoi ?
    Erreur de format d'affichage. Tu dois utiliser "%d" alors qu'il vaudrait mieux utiliser "%lu" ou mieux "%x" (ou "%p"). J'ai justement écrit un petit truc à ce propos ici.

    Citation Envoyé par naute Voir le message
    J'ai essayé avec :
    ça fonctionne mais gare aux débordements.
    Oui. Ton compilateur a même dû te dire que gets() est dangereuse. Pour des tests rapides et temporaires pas de souci mais pour un projet ops, faut la bannir.

    Citation Envoyé par naute Voir le message
    Là je ne pige pas trop. Est-ce que ça veut dire que quand tu demandes une allocation mémoire pour un char, du genre :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    reception = malloc(1 * sizeof(char));
    donc 1 octet, on te réserve 8 octets ?
    Non.

    Déjà demander une allocation de 1 (ou 10 ou 50 ou 5000) est inutile. Tu veux 1, tu définis un char. Tu veux 10 ou 50 ou 5000 tu définis un tableau. malloc() ne s'utilisera que si tu ne connais pas la taille à l'avance au moment où tu écris ton code (taille calculée, lue dans un fichier, etc).

    Mais ce que je voulais dire, c'est que sizeof(x) (VF "taille de x") donne juste et uniquement la taille de la variable "x", rien de plus. Et il ne se préoccupe absolument pas de savoir si "x" référence une zone allouée ou quoi que ce soit d'autre.
    Donc ton pointeur int * temp c'est déjà en lui-même un espace mémoire. Espace pour stocker une adresse. Tout comme quand tu définis double d tu définis une variable"d" ayant une taille suffisante pour stocker un double, quand tu écris int * temp c'est la même chose, tu définis une variable "temp" ayant une taille suffisante pour stocker un int étoile (l'adresse d'un int). Et quand on parle d'OS 64 bits, ça veut dire qu'on parle d'OS ayant des adresses sur 64 bits (donc sur 8 octets). Donc "temp" fait 8 octets (comme un double).
    L'usage est d'ailleurs de coller l'étoile d'un côté ou de l'autre, pas de la laisser au milieu comme une bouse. Soit tu écris int *temp soulignant par là que tu privilégies l'entier "*temp", soit tu écris int* temp, soulignant que tu privilégies l'adresse "temp". Dans tous les cas pour le compilateur c'est pareil, et dans tous les cas tu peux travailler avec "temp" comme avec "*temp". C'est juste une astuce pour aider à la relecture.
    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]

  11. #11
    Rédacteur

    Avatar de naute
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2009
    Messages
    708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2009
    Messages : 708
    Par défaut
    Bonsoir Sve@r .

    Citation Envoyé par Sve@r Voir le message
    Erreur de format d'affichage. Tu dois utiliser "%d" alors qu'il vaudrait mieux utiliser "%lu" ou mieux "%x" (ou "%p"). J'ai justement écrit un petit truc à ce propos ici.
    J'ai suivi ton lien : excellente explication ! ce que j'en retiens surtout, c'est qu'il faut bien faire le distinguo entre la valeur et la manière dont on l'affiche.

    Citation Envoyé par Sve@r Voir le message
    Oui. Ton compilateur a même dû te dire que gets() est dangereuse. Pour des tests rapides et temporaires pas de souci mais pour un projet ops, faut la bannir.
    Tout à fait. Je compile avec GCC sous code::blocks et j'ai droit à mon petit rectangle rouge .

    Citation Envoyé par Sve@r Voir le message
    Mais ce que je voulais dire, c'est que sizeof(x) (VF "taille de x") donne juste et uniquement la taille de la variable "x", rien de plus. Et il ne se préoccupe absolument pas de savoir si "x" référence une zone allouée ou quoi que ce soit d'autre.
    OK, pigé !

    Citation Envoyé par Sve@r Voir le message
    L'usage est d'ailleurs de coller l'étoile d'un côté ou de l'autre, pas de la laisser au milieu comme une bouse.
    Cette écriture n'est pas de mon fait. Elle provient du tutoriel dont je parle en début de post. Personnellement, je privilégie l'écriture int *temp; qui permet notamment de déclarer plusieurs pointeurs sur la même ligne comme int *temp1, *temp2;.


    Merci pour ce complément d'information ,
    amicalement,
    naute

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

Discussions similaires

  1. utilisation de malloc dans un fichier
    Par nemesys971 dans le forum C
    Réponses: 10
    Dernier message: 09/05/2006, 17h33
  2. [Select()/Focus()] Pb dans l'utilisation de ces méthodes
    Par Kylen dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 23/06/2005, 14h54
  3. Erreur dans l'utilisation de SWAP
    Par mire dans le forum Langage
    Réponses: 12
    Dernier message: 15/03/2003, 21h39

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