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 :

SegFault coriace et pointeur de pointeur


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 12
    Par défaut SegFault coriace et pointeur de pointeur
    Bonjour,
    Je me prend la tête sur une fonction en objective C (qui est quasi équivalente a une fonction C, je n'utilise pas d'objet, donc je me permet de poster ça ici ..)
    L'idée c'est de construire un tableau de pointeur vers des caractères, la fonction permet une réalocation du tableau pour accueillir à chaque fois une nouvelle chaine. Je n'ai pas de sigfault sur le moment, par contre plus loin dans le programme oui, et c'est directement lié à cette fonction car quand je met en paramètres cette ligne dans le "else", je n'ai plus de sigFault. Idem si mon tableau de pointeur p_listCol fait une taille de un, pas de problème, dès lors que je passe à deux, j'ai de nouveau un problème plus loin.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *p_listCol[**p_sizeList]=(char*)arg;
    L'appel de ma fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
      char **p_listArg = NULL;
      int *p_sizeL = NULL;
     
      [archiver utils_addArgToList:&p_listArg withArg:"BLABLABLABLA" size:&p_sizeL];
      [archiver utils_addArgToList:&p_listArg withArg:"BLOUBLOUBLOUBLOU" size:&p_sizeL];
      [archiver utils_addArgToList:&p_listArg withArg:"BLOBLOBLOBLOBLOBLBOLBOLBOBLBO" size:&p_sizeL];
     
      free(p_sizeL);
      free(p_listArg);
    La fonction :
    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
     
    - (void)utils_addArgToList:(char***)p_listCol withArg:(const char*)arg size:(int**)p_sizeList{
     
      if (*p_sizeList == NULL){
        printf(" SIZE LIST = NUL\n");
        *p_sizeList = malloc(1*sizeof(int));
        **p_sizeList=0;
     
        *p_listCol=malloc(1*sizeof(char*));
        *p_listCol[**p_sizeList]=(char*)arg;
        printf(" SIZE LIST = %d\n",**p_sizeList);
      }else{
        **p_sizeList += 1;                                                                                             
    *p_listCol=realloc(*p_listCol,**p_sizeList*sizeof(char*));                                                                                                                                 
        *p_listCol[**p_sizeList]=(char*)arg;
      }
    Merci d'avance pour votre aide précieuse !
    Seb

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    J'ai l'impression que tu accèdes à des endroit du tableau non alloués : lors du premier passage, tu alloue un tableau de taille 1, au second passage aussi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    else{
        **p_sizeList += 1; 
        *p_listCol=realloc(*p_listCol,(1 + **p_sizeList)*sizeof(char*));
        *p_listCol[**p_sizeList]=(char*)arg;
      }
    Au passage, tu utilises = pour affecter les éléments de p_listCol, j'espère que ce n'est pas pour copier des chaines de caractères (dans ce cas, il faut utiliser strcpy, strdup ...).

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 12
    Par défaut
    Merci pour ton aide, c'est exact, le +1 m'avait échappé sur le realloc m'avait échappé, merci!
    C'est corrigé, mais le segfault reste.
    Pour ce qui est de la copie de string dans un tableau, j'ai vu à plusieurs endroit que l'on pouvait faire directement *tab[0]=constante char

    De plus le compilateur ne dit rien et la sortie outre le fait que j'ai un sigfault à un autre endroit du programme du à cette ligne, les constantes que je passe s'affiche bien lors de mon test. J'arrive à parcourir et afficher le texte correctement, sans artefact ...

  4. #4
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par reyman Voir le message
    Pour ce qui est de la copie de string dans un tableau, j'ai vu à plusieurs endroit que l'on pouvait faire directement *tab[0]=constante char
    C'est valable pour une initialisation, pas pour une affectation.

    En gros, si on écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char ma_chaine[] = "blahblah";
    De la mémoire sera allouée est pointée par ma_chaine.
    Mais si on écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char ma_chaine[64];
    ma_chaine = "blahblah";
    Le pointeur 'ma_chaine' pointera sur un bout de mémoire qui est local à la fonction en cours.

    Pour copier une chaine de caractère, on peut utiliser malloc + strcpy ou strdup si dispo sur la machine utilisée

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    mabu :
    Mais si on écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char ma_chaine[64];
    ma_chaine = "blahblah";
    Le pointeur 'ma_chaine' pointera sur un bout de mémoire qui est local à la fonction en cours.
    On n'a aucune chance d'écrire un tel code et de le voir accepté par le compilateur : il est impossible d'écrire tableau = ...

    La chaine "blahblah" n'est pas allouée dans un bout de mémoire local à la fonction.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 12
    Par défaut
    J'ai suivi tes conseils et remplacer le code d'affectation par des strcopy, en ayant soin de faire des calloc avant ... mais la sigfault reste malheuresement ..

    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
    25
    26
    27
    28
    29
    30
    - (void)utils_addArgToList:(char***)p_listCol withArg:(const char*)arg size:(int**)p_sizeList{
     
      if (*p_sizeList == NULL){
        printf(" SIZE LIST = NUL\n");
        *p_sizeList = malloc(1*sizeof(int));
        **p_sizeList=0;
     
        *p_listCol=malloc(1*sizeof(char*));
     
        *p_listCol[**p_sizeList]=calloc(strlen(arg)+1,sizeof(char));
        strcpy(*p_listCol[**p_sizeList],(char*)arg);
     
        printf(" SIZE LIST = %d\n",**p_sizeList);
      }else{
        **p_sizeList += 1;
        //printf("SIZE LIST %d\n",**p_sizeList);                                                                                                                 
        //printf("REALOC = %ld\n",**p_sizeList*sizeof(char*));                                                                                                   
        *p_listCol=realloc(*p_listCol,(**p_sizeList + 1)*sizeof(char*));                                                                                                 
     
        *p_listCol[**p_sizeList]=calloc(strlen(arg)+1,sizeof(char));
        strcpy(*p_listCol[**p_sizeList],(char*)arg);
      }
     
      int i=0;
     
      for (i;i<(**p_sizeList);i++){
        printf("NEW LIST : %s\n",*p_listCol[i]);
      }
     
    }

  7. #7
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par diogene Voir le message
    mabu :

    On n'a aucune chance d'écrire un tel code et de le voir accepté par le compilateur : il est impossible d'écrire tableau = ...

    La chaine "blahblah" n'est pas allouée dans un bout de mémoire local à la fonction.
    Oui, j'ai voulu simplifier mon exemple, je n'aurai pas du : voici donc l'exemple en question :
    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
    #include <stdio.h>
     
    void test(char *p) 
    {
        p = "blabla";
     
        printf("p from test: \"%s\"\n", p);
    }
     
    int main(void) 
    {
        char p[64];
     
        test(p);
     
        printf("p from main: \"%s\"\n", p);
        return 0;
    }
    donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    p from test: "blabla"
    p from main: "`oÿañ"

  8. #8
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Problème de priorité d'opérateur :
    *p_listCol[...] correspond à *(p_listCol[...])
    alors que le code devrait être (*p_listCol)[...]

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 12
    Par défaut
    Citation Envoyé par diogene Voir le message
    Problème de priorité d'opérateur :
    *p_listCol[...] correspond à *(p_listCol[...])
    alors que le code devrait être (*p_listCol)[...]
    C'était effectivement ça, rah la loose, c'était vicieux... Un grand merci donc pour votre aide
    Je fait jamais gaffe à ce genre de truc, ca m'apprendra ..

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

Discussions similaires

  1. Pointeurs et pointeurs de pointeurs
    Par wallace27 dans le forum C
    Réponses: 10
    Dernier message: 09/04/2015, 22h07
  2. Réponses: 21
    Dernier message: 06/08/2009, 09h31
  3. Réponses: 6
    Dernier message: 26/05/2007, 00h33
  4. pointeur de pointeur
    Par petdelascar dans le forum C
    Réponses: 2
    Dernier message: 05/12/2005, 10h26
  5. pointeur sur pointeur
    Par gaut dans le forum C
    Réponses: 3
    Dernier message: 01/11/2005, 21h30

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