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 :

erreur de strlen()


Sujet :

C

  1. #1
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2012
    Messages
    359
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Avril 2012
    Messages : 359
    Points : 738
    Points
    738
    Billets dans le blog
    2
    Par défaut erreur de strlen()
    Bonjour,

    J'ai un problème avec l'appel de la fonction strlen(), dans le fichier parser.c (ligne 22) qui provoque l'erreur 0xc0000005 (sous Windows 7). Au début, j'ai supposé que c'était dû à un "\0" de fin absent de la chaîne (dans la fonction calloc_codel() du fichier listing.c) mais ça n'a pas l'air d'être le cas. Voici les codes.

    main.c
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include "global_const.h"
    #include "struct.h"
    //#include "help.h"
    #include "reader.h"
    #include "listing.h"
    #include "parser.h"
     
    /*
    ** Le programme utilise les codes d'erreurs suivants:
    **
    **   -1              Erreur interne au programme dû à une erreur
    **                   d'appel de fonction
    **
    **   -2              Erreur interne au programme dû à  un param√®tre
    **                   d'appel du programme absent
    **
    **   -3              Erreur interne au programme dû à  un param√®tre
    **                   d'appel du programme invalide
    **
    **   -4              Erreur interne au programme dû à  un param√®tre
    **                   d'appel du programme ayant une taille excessive
    **
    **   N               Ou N est le nombre d'erreur de syntaxe rencontré
    **                   par le pr√©processeur et n'ayant pas provoqué la
    **                   terminaison du traitement. N est toujours positif
    **
    **   0               Aucune erreur.
    */
     
    int             main(int argc, char *argv[])
    {
      int           i, j;
      //unsigned long err_cnt;
     
      const char    *sp_format2;
      const char    *sp_format3;
      //const char    *sp_format4;
      const char    *sp_argument_size_execessed;
      const char    *sp_invalid_argument;
      const char    *sp_argument_not_found;
      const char    *sp_infile_argument;
      const char    *sp_outfile_argument;
      const char    *sp_include_argument;
      const char    *sp_help_argument;
      const char    *sp_memory_allocation_failed;
      const char    *sp_file_openning_failed;
      const char    *sp_file_closing_failed;
      //const char    *sp_output_file_not_created;
      const char    *sp_output_func_failed;
      const char    *sp_func_call_failed;
      const char    *sp_use_info;
      //const char    *sp_preprocessing_terminated;
      const char    *sp_tmp_data;
      //const char    *sp_error;
      const char    *sp_func_read_file;
     
      char          *sp_infile_path;
      char          *sp_outfile_path;
      char          *sp_include_path;
      char          *sp_tmp;
     
      FILE          *fp_infile;
      FILE          *fp_outfile;
     
      t_codel       s_code_listing;
      t_tok         s_first_token;
      t_wd          s_data;
     
      sp_format2 = "\n%s: '%s'.\n\n";
      sp_format3 = "\n%s: '%s'.\n%s\n\n";
      //sp_format4 = "\n%s with %d %s.\n%s.\n\n";
      sp_argument_size_execessed = "Argument size excessed";
      sp_invalid_argument = "Invalid argument";
      sp_argument_not_found = "Argument not found";
      sp_infile_argument = "-if";
      sp_outfile_argument = "-of";
      sp_include_argument = "-inc";
      sp_help_argument = "-help";
      sp_memory_allocation_failed = "Memory allocation failed";
      sp_file_openning_failed = "File openning failed";
      sp_file_closing_failed = "File closing failed";
      //sp_output_file_not_created = "Output file not created";
      sp_output_func_failed = "Output function failed";
      sp_func_call_failed = "Function call failed";
      sp_use_info = "Use 'upp -help' for more information.";
      //sp_preprocessing_terminated = "Preprocessing terminated";
      sp_tmp_data = "temp data";
      //sp_error = "error";
      sp_func_read_file = "read_file";
     
      sp_infile_path = NULL;
      sp_outfile_path = NULL;
      sp_include_path = NULL;
      sp_tmp = NULL;
     
      fp_infile = NULL;
      fp_outfile = NULL;
     
      s_code_listing.previous = NULL;
      s_code_listing.content = NULL;
      s_code_listing.next = NULL;
     
      s_first_token.previous = NULL;
      s_first_token.name = NULL;
      s_first_token.type = 0x00;
      for (i = 0; i < PP_ARG_MAX; i++)
        s_first_token.param[i] = NULL;
      s_first_token.definition = NULL;
      s_first_token.next = NULL;
     
      s_data.include_path = NULL;
      s_data.tmp_file = NULL;
      s_data.code_listing = &s_code_listing;
      s_data.token_listing = &s_first_token;
     
      /*
      ** Traitement des parmètres d'appel.
      */
      if (argc > 1)
      {
        if ((sp_tmp = calloc(6, sizeof(char))) == NULL)
        {
          fprintf(stderr, sp_format2, sp_memory_allocation_failed, sp_tmp_data);
          exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
        }
        for (i = 0; i < 6; i++)
          sp_tmp[i] = 0;
        for (i = 1; i < argc; i++)
        {
          if (strlen(argv[i]) > 5)
          {
            fprintf(stderr, sp_format2, sp_argument_size_execessed, argv[i]);
            free(sp_tmp);
            if (sp_infile_path)
              free(sp_infile_path);
            if (sp_outfile_path)
              free(sp_outfile_path);
            if (sp_include_path)
              free(sp_include_path);
            exit(INTERNAL_ERROR_ARGUMENT_SIZE_EXCESSED);
          }
          strncpy(sp_tmp, argv[i], 6);
          for (j = 0; j < strlen(sp_tmp); j++)
            sp_tmp[j] = tolower(sp_tmp[j]);
          if (strcmp(sp_tmp, sp_help_argument) == 0)
          {
            //print_help();
            free(sp_tmp);
            if (sp_infile_path)
              free(sp_infile_path);
            if (sp_outfile_path)
              free(sp_outfile_path);
            if (sp_include_path)
              free(sp_include_path);
            exit(EXIT_SUCCESS);
          }
          else if (strcmp(sp_tmp, sp_infile_argument) == 0 && sp_infile_path == NULL)
          {
            if (strlen(argv[++i]) > FULLPATH_MAX)
            {
              fprintf(stderr, sp_format2, sp_argument_size_execessed, argv[i]);
              free(sp_tmp);
              if (sp_outfile_path)
                free(sp_outfile_path);
              if (sp_include_path)
                free(sp_include_path);
              exit(INTERNAL_ERROR_ARGUMENT_SIZE_EXCESSED);
            }
            if ((sp_infile_path = strdup(argv[i])) == NULL)
            {
              fprintf(stderr, sp_format2, sp_memory_allocation_failed, sp_infile_path);
              free(sp_tmp);
              if (sp_outfile_path)
                free(sp_outfile_path);
              if (sp_include_path)
                free(sp_include_path);
              exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
            }
          }
          else if (strcmp(sp_tmp, sp_outfile_argument) == 0 && sp_outfile_path == NULL)
          {
            if (strlen(argv[++i]) > FULLPATH_MAX)
            {
              fprintf(stderr, sp_format2, sp_argument_size_execessed, argv[i]);
              free(sp_tmp);
              if (sp_infile_path)
                free(sp_infile_path);
              if (sp_include_path)
                free(sp_include_path);
              exit(INTERNAL_ERROR_ARGUMENT_SIZE_EXCESSED);
            }
            if ((sp_outfile_path = strdup(argv[i])) == NULL)
            {
              fprintf(stderr, sp_format2, sp_memory_allocation_failed, sp_outfile_path);
              free(sp_tmp);
              if (sp_infile_path)
                free(sp_infile_path);
              if (sp_include_path)
                free(sp_include_path);
              exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
            }
          }
          else if (strcmp(sp_tmp, sp_include_argument) == 0 && sp_include_path == NULL)
          {
            if (strlen(argv[++i]) > FULLPATH_MAX)
            {
              fprintf(stderr, sp_format2, sp_argument_size_execessed, argv[i]);
              free(sp_tmp);
              if (sp_infile_path)
                free(sp_infile_path);
              if (sp_outfile_path)
                free(sp_outfile_path);
              exit(INTERNAL_ERROR_ARGUMENT_SIZE_EXCESSED);
            }
            if ((sp_include_path = strdup(argv[i])) == NULL)
            {
              fprintf(stderr, sp_format2, sp_memory_allocation_failed, sp_include_path);
              free(sp_tmp);
              if (sp_infile_path)
                free(sp_infile_path);
              if (sp_outfile_path)
                free(sp_outfile_path);
              exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
            }
          }
          else
          {
            fprintf(stderr, sp_format2, sp_invalid_argument, sp_tmp);
            free(sp_tmp);
            if (sp_infile_path)
              free(sp_infile_path);
            if (sp_outfile_path)
              free(sp_outfile_path);
            if (sp_include_path)
              free(sp_include_path);
            exit(INTERNAL_ERROR_INVALID_ARGUMENT);
          }
          for (j = 0; j < 6; j++)
            sp_tmp[j] = 0;
        }
        free(sp_tmp);
      }
      else
      {
        fprintf(stderr, sp_format3, sp_argument_not_found, sp_infile_argument, sp_use_info);
        exit(INTERNAL_ERROR_ARGUMENT_NOT_FOUND);
      }
     
      /*
      ** Vérification des paramètres fournits.
      **
      ** Si l'un des paramètres suivants n'est pas fournit, le programme se
      ** termine sur une erreur avec le code d'erreur
      ** INTERNAL_ERROR_ARGUMENT_NOT_FOUND.
      **
      ** sp_infile_path
      ** sp_outfile_path
      ** sp_include_path
      */
      if (sp_infile_path == NULL)
      {
        fprintf(stderr, sp_format3, sp_argument_not_found, sp_infile_argument, sp_use_info);
        if (sp_outfile_path)
          free(sp_outfile_path);
        if (sp_include_path)
          free(sp_include_path);
        exit(INTERNAL_ERROR_ARGUMENT_NOT_FOUND);
      }
      if (sp_outfile_path == NULL)
      {
        fprintf(stderr, sp_format3, sp_argument_not_found, sp_outfile_argument, sp_use_info);
        free(sp_infile_path);
        if (sp_include_path)
          free(sp_include_path);
        exit(INTERNAL_ERROR_ARGUMENT_NOT_FOUND);
      }
      if (sp_include_path == NULL)
      {
        fprintf(stderr, sp_format3, sp_argument_not_found, sp_include_argument, sp_use_info);
        free(sp_infile_path);
        free(sp_outfile_path);
        exit(INTERNAL_ERROR_ARGUMENT_NOT_FOUND);
      }
     
      /*
      ** Ouveture des fichiers d'ES et mise à jour de la structure
      ** t_wd s_data.
      **
      ** Si un des fichiers d'ES ne peut être ouvert, le programme se termine avec
      ** le code d'erreur INTERNAL_ERROR_FUNC_CALL_FAILED.
      */
      if ((fp_infile = fopen(sp_infile_path, "r")) == NULL)
      {
        fprintf(stderr, sp_format2, sp_file_openning_failed, sp_infile_path);
        free(sp_infile_path);
        free(sp_outfile_path);
        free(sp_include_path);
        exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
      }
      if ((fp_outfile = fopen(sp_outfile_path, "w")) == NULL)
      {
        fprintf(stderr, sp_format2, sp_file_openning_failed, sp_outfile_path);
        free(sp_infile_path);
        free(sp_outfile_path);
        free(sp_include_path);
        exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
      }
      if ((s_data.tmp_file = tmpfile()) == NULL)
      {
        fprintf(stderr, sp_format2, sp_file_openning_failed, sp_tmp_data);
        free(sp_infile_path);
        free(sp_outfile_path);
        free(sp_include_path);
        exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
      }
      s_data.include_path = sp_include_path;
     
      /*
      ** Appel de la fonction de lecture du fichier d'entrée.
      **
      ** Si la fonction de lecture renvoi une valeur différente de EXIT_SUCCESS,
      ** il y a erreur.
      */
      if ((read_file(fp_infile, &s_code_listing)) != EXIT_SUCCESS)
      {
        fprintf(stderr, sp_format2, sp_func_call_failed, sp_func_read_file);
        free(sp_infile_path);
        free(sp_include_path);
        free(sp_outfile_path);
        exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
      }
     
      /*
      ** Le fichier d'entrée est fermé et le tampon contenant son chemin d'accès
      ** est libéré.
      */
      if ((fclose(fp_infile)) == EOF)
      {
        fprintf(stderr, sp_format2, sp_file_closing_failed, sp_infile_path);
        free(sp_infile_path);
        free(sp_include_path);
        free(sp_outfile_path);
        free_codel(&s_code_listing);
        exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
      }
      free(sp_infile_path);
     
      /*
      ** Appel de le fonction de parsage.
      */
      if (parse_codelisting(&s_data) != EXIT_SUCCESS)
      {
        fprintf(stderr, sp_format2, sp_output_func_failed, sp_tmp_data);
        free_codel(&s_code_listing);
        free(sp_include_path);
        free(sp_outfile_path);
        /*
        ** Inclure la libération des tampons des jetons de définition
        */
        exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
      }
     
      /*
      ** Libération des tampons du listing. Le tampon contenant le chemin d'accès vers les fichiers
      ** d'include est libéré.
      */
      free_codel(&s_code_listing);
      free(sp_include_path);
      /*
      ** Inclure la libération des tampons des jetons de définition
      */
     
      /*
      ** Le fichier temporaire est copié dans le fichier de sortie, les tampons
      ** sont libérés et les fichiers sont fermés.
      */
      if ((sp_tmp = calloc(LINE_MAX_SIZE, sizeof (char))) == NULL)
      {
        fprintf(stderr, sp_format2, sp_memory_allocation_failed, sp_tmp_data);
        free(sp_outfile_path);
        exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
      }
      for (i = 0; i < LINE_MAX_SIZE; i++)
        sp_tmp[i] = 0;
      fseek(s_data.tmp_file, SEEK_SET, 0);
      while (fgets(sp_tmp, LINE_MAX_SIZE, s_data.tmp_file))
      {
        if ((fprintf(fp_outfile, "%s", sp_tmp)) < 0)
        {
          fprintf(stderr, sp_format2, sp_output_func_failed, sp_tmp_data);
          free(sp_outfile_path);
          free(sp_tmp);
          exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
        }
        for (i = 0; i < LINE_MAX_SIZE; i++)
          sp_tmp[i] = 0;
      }
      if ((fclose(fp_outfile)) == EOF)
      {
        fprintf(stderr, sp_format2, sp_file_closing_failed, sp_outfile_path);
        free(sp_outfile_path);
        free(sp_tmp);
        exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
      }
      if ((fclose(s_data.tmp_file)) == EOF)
      {
        fprintf(stderr, sp_format2, sp_file_closing_failed, sp_tmp_data);
        free(sp_outfile_path);
        free(sp_tmp);
        exit(INTERNAL_ERROR_FUNC_CALL_FAILED);
      }
      free(sp_outfile_path);
      free(sp_tmp);
     
      exit(EXIT_SUCCESS);
    }
    global_const.h
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    #ifndef _GLOBAL_CONST_H
    #  define _GLOBAL_CONST_H
     
    /*
    ** Define the maximum length of a path.
    */
    #  include <stdlib.h>
    #  if defined(MAX_PATH) && !defined(PATH_MAX)
    #    define PATH_MAXLENGTH                         MAX_PATH
    #  elif !defined(MAX_PATH) && defined(PATH_MAX)
    #    define PATH_MAXLENGTH                         PATH_MAX
    #  else /* !MAX_PATH && !PATH_MAX */
    #    define PATH_MAXLENGTH                         260
    #  endif /* MAX_PATH && PATH_MAX */
    /*
    ** Define the maximum length of a filename.
    */
    #  include <stdio.h>
    #  ifndef FILENAME_MAX
    #    FILENAME_MAX                                  260
    #  endif /* !FILENAME_MAX */
    /*
    ** Define the maximum length of a fully qualified path.
    ** Fully qualified path have form: <path>//<filename>.
    */
    #  define FULLPATH_MAX                             ((PATH_MAXLENGTH - 1) + (FILENAME_MAX - 1))
     
    /*
    ** Define maximum size of one line for IO function.
    */
    #  define LINE_MAX_SIZE                            8192
     
    /*
    ** Define error code.
    */
    #  if defined(EXIT_SUCCESS) && (EXIT_SUCCESS != 0)
    #    undef EXIT_SUCCESS
    #    define EXIT_SUCCESS                           0
    #  elif !defined(EXIT_SUCCESS)
    #    define EXIT_SUCCESS                           0
    #  endif /* EXIT_SUCCESS */
    #  define INTERNAL_ERROR_FUNC_CALL_FAILED          -1
    #  define INTERNAL_ERROR_ARGUMENT_NOT_FOUND        -2
    #  define INTERNAL_ERROR_INVALID_ARGUMENT          -3
    #  define INTERNAL_ERROR_ARGUMENT_SIZE_EXCESSED    -4
     
    #  define PP_TYPE_DEFINE_WITHOUT_ARG               0x01
    #  define PP_TYPE_DEFINE_WITH_ARG                  0x02
    #  define PP_TYPE_EVAL_WITHOUT_ARG                 0x03
    #  define PP_TYPE_EVAL_WITH_ARG                    0x04
     
    #  define PP_ARG_MAX                               64
     
    #endif /* !_GLOBAL_CONST_H */
    struct.h
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    #include <stdio.h>
    #include "global_const.h"
    #ifndef _STRUCT_H
    #  define _STRUCT_H
     
    /*
    ** s_code_listing est la définition d'une ligne de code sous forme d'une liste doublement chaîné.
    **
    ** Chaque élément de la liste contient:
    **   un pointeur vers l'élément précédent (previous).
    **   un pointeur vers la ligne de code (content).
    **   un pointeur vers l'élément suivant (next).
    */
    typedef struct s_code_listing t_codel;
    struct    s_code_listing
    {
      t_codel *previous;
      char    *content;
      t_codel *next;
    };
     
    /*
    ** s_token_definition est la définition d'une macro sous forme d'une liste doublement chaîné.
    **
    ** Chaque élément de la liste contient:
    **   un pointeur vers l'élément précédent (previous).
    **   un pointeur vers le nom de la macro (name).
    **   le type de la macro (type): PP_TYPE_xyz.
    **   param[] contiennent des pointeurs vers les paramètres de la macro, DOIT SE TERMINER PAR NULL.
    **   un pointeur vers la définition de la macro (definition).
    **   un pointeur vers l'élément suivant (next).
    */
    typedef struct s_token_definition t_tok;
    struct          s_token_definition
    {
      t_tok         *previous;
      char          *name;
      unsigned char type;
      char          *param[PP_ARG_MAX];
      char          *definition;
      t_tok         *next;
    };
     
    /*
    ** s_workdata contient:
    **   le pointeur vers le chemin d'accès vers les fichiers includes (include_path).
    **   le pointeur vers le fichier source (in_file).
    **   le pointeur vers le premier élément du listing (code_listing)
    **   le pointeur vers le premier jeton de définition (token_listing)
    */
    typedef struct s_workdata
    {
      char         *include_path;
      FILE         *tmp_file;
      t_codel      *code_listing;
      t_tok        *token_listing;
    }              t_wd ;
     
    /*typedef struct s_return_token
    {
      t_tok        *target;
      int          exit_code;
    }              t_rettok;*/
    #endif /* !_STRUCT_H */
    reader.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "struct.h"
    #ifndef _READER_H
    #  define _READER_H
    int read_file(FILE *fp_infile, t_codel *s_code_listing);
    #endif /* !_READER_H */
    reader.c
    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
    31
    32
    33
    34
    35
    36
    #include <stdlib.h>
    #include <stdio.h>
    #include "global_const.h"
    #include "struct.h"
    #include "reader.h"
    #include "listing.h"
     
    int             read_file(FILE *fp_infile, t_codel *s_code_listing)
    {
      int           i;
      char          *sp_tmp;
     
      if ((sp_tmp = calloc(LINE_MAX_SIZE, sizeof (char))) == NULL)
        return(INTERNAL_ERROR_FUNC_CALL_FAILED);
      for (i = 0; i < LINE_MAX_SIZE; i++)
        sp_tmp[i] = 0;
     
      /*
      ** Création du listing.
      */
      while(fgets(sp_tmp, LINE_MAX_SIZE, fp_infile))
      {
        if ((calloc_codel(s_code_listing, sp_tmp)) == INTERNAL_ERROR_FUNC_CALL_FAILED)
        {
          free(sp_tmp);
          return(INTERNAL_ERROR_FUNC_CALL_FAILED);
        }
     
        for (i = 0; (i < LINE_MAX_SIZE) && (sp_tmp[i]); i++)
          sp_tmp[i] = 0;
      }
     
      free(sp_tmp);
     
      return(EXIT_SUCCESS);
    }
    listing.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include "struct.h"
    #ifndef _LISTING_H
    #  define _LISTING_H
    int calloc_codel(t_codel *s_codel, const char *sp_tmp);
    void free_codel(t_codel *s_codel);
    #endif /* !_LISTING_H */
    listing.c
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #include <stdlib.h>
    #include <string.h>
    #include "global_const.h"
    #include "listing.h"
     
    int       calloc_codel(t_codel *s_codel, const char *sp_tmp)
    {
      t_codel *current;
      t_codel *next;
     
      current = s_codel;
     
      while (current->next != NULL)
      {
        current = current->next;
      }
      if ((next = calloc(1, sizeof(t_codel))) == NULL)
        return(INTERNAL_ERROR_FUNC_CALL_FAILED);
      next->previous = current;
      next->next = NULL;
      if ((next->content = strdup(sp_tmp)) == NULL)
      {
        free(next);
        return(INTERNAL_ERROR_FUNC_CALL_FAILED);
      }
      current->next = next;
     
      return(EXIT_SUCCESS);
    }
     
    void      free_codel(t_codel *s_codel)
    {
      t_codel *next;
      t_codel *tmp;
     
      next = s_codel;
     
      do
      {
        tmp = next;
        next = next->next;
        if (tmp->content)
          free(tmp->content);
        if (tmp->previous)
          free(tmp);
      } while (next != NULL);
    }
    parser.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #ifndef _PARSER_H
    #  define _PARSER_H
    int parse_codelisting(t_wd *s_workdata);
    #endif /* !_PARSER_H */
    parser.c
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    #include <stdio.h>
    #include <string.h>
    #include "global_const.h"
    #include "struct.h"
     
    int       parse_codelisting(t_wd *s_workdata)
    {
      t_codel *next_cdl;
      char    *sp_tmp_out;
      int     i, current_index;
     
      next_cdl = s_workdata->code_listing;
     
      if ((sp_tmp_out = calloc(LINE_MAX_SIZE, sizeof(char))) == NULL)
        return(INTERNAL_ERROR_FUNC_CALL_FAILED);
      for (i = 0; i < LINE_MAX_SIZE; i++)
        sp_tmp_out[i] = 0;
     
      do
      {
        current_index = 0;
        for (i = 0; i < strlen(next_cdl->content); i++)
        {
          switch(next_cdl->content[i])
          {
            case 0x5C:
              // échappement de fin de ligne
              //break;
            case 0x28:
              // parenthèse ouvrante
              //break;
            case 0x29:
              // parenthèse fermante
              //break;
            case 0x0A:
            case 0x0D:
            default:
              sp_tmp_out[current_index] = next_cdl->content[i];
              current_index += 1;
              break;
          }
        }
        sp_tmp_out[current_index] = 0;
     
        fprintf(s_workdata->tmp_file, "%s", sp_tmp_out);
     
        for (i = 0; i < strlen(sp_tmp_out); i++)
          sp_tmp_out[i] = 0;
     
        next_cdl = next_cdl->next;
      } while (next_cdl);
     
      free(sp_tmp_out);
     
      return(EXIT_SUCCESS);
    }
    Le gourou dicte la ligne (de commande) à suivre ...

    Penser à lire le Tutoriel Batch ou a consulter la FAQ Batch et ses contributions,
    ainsi que le Cour sur la ligne de commande et des scripts

  2. #2
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    C'est très difficile de déterminer la cause du problème comme ça, sans essayer avec un debugger.
    En passant, tu devrais diviser ta fonction main() en sous-fonctions, les fonctions longues sont très difficiles à suivre.

    A ta place: soit j'utiliserais un debugger pour comprendre dans quel état on se trouve au moment du crash, soit je m'arrangerais pour afficher le contenu de next_cdl->content ou la valeur du pointeur next_cdl.

  3. #3
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2012
    Messages
    359
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Avril 2012
    Messages : 359
    Points : 738
    Points
    738
    Billets dans le blog
    2
    Par défaut
    J'ai finalement trouvé une solution mais je ne comprend pas exactement pourquoi elle fonction. J'ai remarqué que fprintf() m'affiché la chaîne, du coup j'ai utilisé snprintf(). Je vais essayer dans un debuger mais j'ai pas vraiment les compétences pour en tirer le meilleur parti.

    Les questions qui se pose sont les suivantes:
    - Pourquoi ça segfault avec une fonction qui opére directement sur la chaîne et pas avec une fonction d'impression formaté (si la réponse recoupe les suivantes, ignoré cette question) ?
    - Y a t-il un segment de donnée par fonction dans un programme ?
    - Si oui, qu'est-ce qui fait que la fonction d'impression formaté, elle, peut lire la chaîne sans segfault dans un segment qui n'est pas le sien ?

    parser.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #ifndef _PARSER_H
    #  define _PARSER_H
    int parse_preprocessor(const char *sp_strin, char *sp_strout, const int strlen_out, t_wd *s_workdata);
    int parse_C_code(const char *sp_strin, char *sp_strout, const int strlen_out, t_wd *s_workdata);
    int parse_codelisting(t_wd *s_workdata);
    #endif /* !_PARSER_H */
    parser.c
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    int   parse_preprocessor(const char *sp_strin, char *sp_strout, const int strlen_out, t_wd *s_workdata)
    {
      int i, current_index;
      const int strlen_in;
     
      current_index = 0;
      strlen_in = (int) (strlen(sp_strin));
     
      for (i = 0; (i < strlen_in) && (strlen_out >= current_index); i++)
      {
        switch(sp_strin[i])
        {
          case 0x5C:    // <\>
            //break;
          case 0x28:    // <(>
            //break;
          case 0x29:    // <)>
            //break;
          case 0x0A:    // <LF>
          case 0x0D:    // <CR>
          default:
            sp_strout[current_index++] = sp_strin[i];
            break;
        }
      }
      sp_strout[current_index] = 0;
      return(EXIT_SUCCESS);
    }
     
     
    int parse_C_code(const char *sp_strin, char *sp_strout, const int strlen_out, t_wd *s_workdata)
    {
      return(EXIT_SUCCESS);
    }
     
     
    int       parse_codelisting(t_wd *s_workdata)
    {
      t_codel *next_cdl;
      char    *sp_tmp_in;
      char    *sp_tmp_out;
      int     i, current_index;
     
      next_cdl = s_workdata->code_listing;
     
      if ((sp_tmp_in = calloc(LINE_MAX_SIZE, sizeof(char))) == NULL)
        return(INTERNAL_ERROR_FUNC_CALL_FAILED);
      for (i = 0; i < LINE_MAX_SIZE; i++)
        sp_tmp_in[i] = 0;
     
      if ((sp_tmp_out = calloc(LINE_MAX_SIZE, sizeof(char))) == NULL)
        return(INTERNAL_ERROR_FUNC_CALL_FAILED);
      for (i = 0; i < LINE_MAX_SIZE; i++)
        sp_tmp_out[i] = 0;
     
      do
      {
        snprintf(sp_tmp_in, LINE_MAX_SIZE, "%s", next_cdl->content);
     
        current_index = 0;
        i = 0;
     
        while (sp_tmp_in[i] == 0x20 || sp_tmp_in[i] == 0x09 || sp_tmp_in[i] == 0x0A || sp_tmp_in[i] == 0x0D)
          sp_tmp_out[current_index++] = sp_tmp_in[i++];
     
     
        if (sp_tmp_in[i] == '#')
        {
          /*
          ** Concaténation des lignes faisant partie de la même macro dans sp_tmp_in (limite d'une macro à 
          ** LINE_MAX_SIZE caractères + les échappements éventuels de fin de ligne).
          */
          if (parse_preprocessor((sp_tmp_in + i - 1), (sp_tmp_out + current_index - 1), (LINE_MAX_SIZE - current_index - 1), s_workdata))
          {
            free(sp_tmp_in);
            free(sp_tmp_out);
            return(INTERNAL_ERROR_FUNC_CALL_FAILED);
          }
        }
        else if (sp_tmp_in[i] != 0x00)
        {
          if (parse_C_code((sp_tmp_in + i - 1), (sp_tmp_out + current_index - 1), (LINE_MAX_SIZE - current_index - 1), s_workdata))
          {
            free(sp_tmp_in);
            free(sp_tmp_out);
            return(INTERNAL_ERROR_FUNC_CALL_FAILED);
          }
        }
        else
          sp_tmp_out[current_index] = 0x00;
     
        fprintf(s_workdata->tmp_file, "%s", sp_tmp_out);
     
        for (i = 0; i < LINE_MAX_SIZE; i++)
          sp_tmp_in[i] = 0;
     
        for (i = 0; i < LINE_MAX_SIZE; i++)
          sp_tmp_out[i] = 0;
     
        next_cdl = next_cdl->next;
      } while (next_cdl);
     
      free(sp_tmp_in);
      free(sp_tmp_out);
     
      return(EXIT_SUCCESS);
    }
    Le gourou dicte la ligne (de commande) à suivre ...

    Penser à lire le Tutoriel Batch ou a consulter la FAQ Batch et ses contributions,
    ainsi que le Cour sur la ligne de commande et des scripts

  4. #4
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    Citation Envoyé par InitSreen Voir le message
    J'ai finalement trouvé une solution mais je ne comprend pas exactement pourquoi elle fonction. J'ai remarqué que fprintf() m'affiché la chaîne, du coup j'ai utilisé snprintf(). Je vais essayer dans un debuger mais j'ai pas vraiment les compétences pour en tirer le meilleur parti.
    Génial, ça va être l'occasion d'apprendre :-)
    En plus, c'est pas pour dire, mais y a rien qui m'inquiète plus que trouver une solution qui fonctionne sans que je sache pourquoi. Tu imagines si tu devais monter dans un avion où juste avant le décollage on te dirait "Ah oui y avait une grosse alarme qui sonnait tout à l'heure concernant le réacteur. On a revissé un boulon sur le siège d'un passager et maintenant ça sonne plus... On décolle!" ?


    Citation Envoyé par InitSreen Voir le message
    - Pourquoi ça segfault avec une fonction qui opére directement sur la chaîne et pas avec une fonction d'impression formaté (si la réponse recoupe les suivantes, ignoré cette question) ?
    Je ne comprends pas très bien comment tu as remplacé le code précédent par un snprintf().


    Citation Envoyé par InitSreen Voir le message
    - Y a t-il un segment de donnée par fonction dans un programme ?
    Tu entends quoi par "segment de donnée" ?
    Une fonction utilise généralement un peu d'espace mémoire "privé" sur ce qu'on appelle la pile. Quand tu déclares une variable automatique par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void mafonction (int parametre) /* parametre est alloué sur la pile */
    {
       int a; /* ceci aussi est alloué sur la pile */
    }
    Cet espace est différent du "tas", que l'on accède via "malloc()" notamment.
    Je mets des guillemets autour de "privé" parce que ce n'est pas aussi simple. Un programme mal écrit peut tout à fait aller écraser les valeurs présentes sur la pile, et dans certains cas il est tout à fait possible que ça ne plante pas.

    Citation Envoyé par InitSreen Voir le message
    - Si oui, qu'est-ce qui fait que la fonction d'impression formaté, elle, peut lire la chaîne sans segfault dans un segment qui n'est pas le sien ?
    Suivant le traitement qu'elle fait, elle peut tout a fait ne pas provoquer de plantage. Mais comme je disais plus haut, je n'ai pas tout à fait compris comment tu as modifié ton code.

  5. #5
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Ou encore mieux : si tu sais que ton programme plante dans strlen, tu te réécris un petite fonction qui fait la même chose (my_strlen par-exemple) et après t'affiches les infos dont tu pourrais avoir besoin (pointeur, chaîne "anormalement" longue, etc..).

  6. #6
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2012
    Messages
    359
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Avril 2012
    Messages : 359
    Points : 738
    Points
    738
    Billets dans le blog
    2
    Par défaut
    Avant de répondre, prenez le temps de lire le code.

    Une fonction utilise généralement un peu d'espace mémoire "privé" sur ce qu'on appelle la pile.
    Pour sûr... Certes les paramètres de fonction sont placé sur la pile, pour le reste ça reste voir

    Génial, ça va être l'occasion d'apprendre :-)

    http://fr.wikipedia.org/wiki/Segment_de_donn%C3%A9es
    Le gourou dicte la ligne (de commande) à suivre ...

    Penser à lire le Tutoriel Batch ou a consulter la FAQ Batch et ses contributions,
    ainsi que le Cour sur la ligne de commande et des scripts

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

Discussions similaires

  1. Erreur de segmentation strlen
    Par Xavi91 dans le forum C
    Réponses: 6
    Dernier message: 18/12/2011, 18h41
  2. Erreur fréquente avec ASP et IIS
    Par Community Management dans le forum ASP
    Réponses: 2
    Dernier message: 11/02/2004, 22h20
  3. Réponses: 2
    Dernier message: 27/05/2002, 19h46
  4. erreur IDL:omg.org/CORBA/MARSHAL:1.0
    Par Pinggui dans le forum CORBA
    Réponses: 3
    Dernier message: 13/05/2002, 15h05
  5. [Kylix] Erreur objet
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 22/03/2002, 09h41

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