MickMRCX
MickMRCX

Reputation: 153

allocated variable inaccessible

I'm working on a script which means to put a text at the end of a PostScript file before converting it into a pdf file.

int main(int argc, char *argv[]){
    // Déclaration des variables

    // Fichier source
    char *source;
    // Extension du fichier source
    char *extension;
    // Fichier de parametre
    char *fichierPar;
    // Numero et Type de folio du fichier
    char *numeroFolio;
    char *typeFolio;

    // Tableaux contenant les types de folio a scanner
    // suivant le numero de folio
    char **t_F000 = NULL;

    // Allocation des espaces mémoires nécessaires aux variables
    source = malloc(sizeof(char) * strlen(argv[1]));
    fichierPar = malloc(sizeof(char) * strlen(argv[2]));
    extension = malloc(sizeof(char) * 5);
    typeFolio = malloc(sizeof(char) * 4);
    numeroFolio = malloc(sizeof(char) * 4);

    // Grille de parametre
    // AJUSTER LA TAILLE DU TABLEAU AVEC LE FICHIER DE LOGO.PAR
    // DANS verification.h
    Grille t_Grilles[NBGRILLE];

    // On copie les arguments dans des varibles plus explicites
    strcpy(source, argv[1]);
    strcpy(fichierPar, argv[2]);

    // GetFolio appel getNumeroFolio qui appel getTypeFolio
    // Ces deux fonctions extraient du nom de fichier
    // le numero et le type de folio
    getFolio(source, numeroFolio, typeFolio);

    printf("strlen : %d\n", strlen(numeroFolio));
    fflush(stdout);
    printf("numero : %s\n", numeroFolio);
    fflush(stdout);

    // Lecture du fichier LOGO.PAR et enregistrement en mémoire
    chargerGrilles(fichierPar, t_Grilles);

    printf("bonjour\n");
    fflush(stdout);

    printf("strlen : %d\n", strlen(numeroFolio));
    fflush(stdout);

    printf("numero : %s", numeroFolio);
    fflush(stdout);

The work doesn't stop there but I'm blocking on this point.
Here is the code of ChargerGrille();

void chargerGrilles(char *fichierPar, Grille t_Grilles[]){
    FILE *fdParam;
    char *ligne;
    Grille *grille;
    int inc = 0;

    grille = malloc(sizeof(Grille));

    ligne = malloc(sizeof(char) * 100);

    fdParam = fopen(fichierPar, "rb");
    verifierOuverture(fdParam, fichierPar);

    while(fgets(ligne, 100, fdParam)){
        if(verifierCommentaire(ligne) != 0){

            remplirGrille(grille, ligne);
            t_Grilles[inc] = *grille;

            inc++;
        }
    }
    fclose(fdParam);
}

void remplirGrille(Grille *grille, char *ligne){
    char *split;

    // Separation sur les espaces
    split = malloc(strlen(ligne));
    split = strtok(ligne, " ");
    strcpy(grille->nom, split);
    split = NULL;
    free(split);

    split = malloc(strlen(ligne));
    split = strtok(NULL, " ");
    grille->posX = strtof(split, NULL);
    split = NULL;
    free(split);

    split = malloc(strlen(ligne));
    split = strtok(NULL, " ");
    grille->posY = strtof(split, NULL);
    split = NULL;
    free(split);

    split = malloc(strlen(ligne));
    split = strtok(NULL, " ");
    grille->longX = strtof(split, NULL);
    split = NULL;
    free(split);

    split = malloc(strlen(ligne));
    split = strtok(NULL, " ");
    grille->hautY = strtof(split, NULL);
    split = NULL;
    free(split);

    split = malloc(strlen(ligne));
    split = strtok(NULL, " ");
    strcpy(grille->logo, split);
    split = NULL;
    free(split);

    printf("Hello World !\n");
    fflush(stdout);
}

There is my declaration of my struct :

struct Grille{
    // Nom du tableau
    char nom[4];

    // Position du point inferieur gauche
    long int posX;
    long int posY;

    // Longueur X
    long int longX;
    // HAUTEUR Y
    long int hautY;

    // Nom du fichier logo.jpg
    char logo[50];
};

typedef struct Grille Grille;

In gdb i can print "source", "extension", "fichierPar", 'numeroFolio" and "typeFolio" just before the call to chargerGrilles(fichierPar, t_Grilles); after that it won't be accessible.

108             chargerGrilles(fichierPar, t_Grilles);
(gdb) print source
$7 = 0x604010 "F290390001_SCH001-2.POS"
(gdb) print numeroFolio
$8 = 0x604090 "001"
(gdb) n
Hello World !
Hello World !
Hello World !
Hello World !
110             printf("bonjour\n");
(gdb) n
bonjour
111             fflush(stdout);
(gdb) print source
$9 = 0x303732 <error: Cannot access memory at address 0x303732>
(gdb) print numeroFolio
$10 = 0x53 <error: Cannot access memory at address 0x53>

If I put a watch on numeroFolio, gdb stop on this line :

t_Grilles[inc] = *grille;

What happened to the allocated memory ? Why the variables' addresses change ?


PS : Do not take care of the many printf/fflush, It's how I try to spot where is the segFault

Upvotes: 0

Views: 210

Answers (1)

LPs
LPs

Reputation: 16213

The problem you are facing is probably caused by accessing t_Grilles array out of bounds into chargerGrilles function. Accessing it out with index > NBGRILLE invokes Undefined Behavior and, in your case, corrupt other main local scoped variables.

You must ensure that the loop while(fgets(ligne, 100, fdParam)) takes care of t_Grilles size.

So a solution can be:

 while((fgets(ligne, 100, fdParam)) && (inc <NBGRILLE)) {
    if(verifierCommentaire(ligne) != 0){

        remplirGrille(grille, ligne);
        t_Grilles[inc] = *grille;

        inc++;
    }
}

Best, from my point of view, is to add a parameter to function to pass array size.

void chargerGrilles(char *fichierPar, Grille t_Grilles[], size_t size)
{
    FILE *fdParam;
    char *ligne;
    Grille *grille;
    size_t inc = 0;

    grille = malloc(sizeof(Grille));

    ligne = malloc(sizeof(char) * 100);

    if ((grille != NULL) && (ligne != NULL))
    {
       fdParam = fopen(fichierPar, "rb");
       verifierOuverture(fdParam, fichierPar);

       while((fgets(ligne, 100, fdParam)) && (inc < size)){
          if(verifierCommentaire(ligne) != 0){

            remplirGrille(grille, ligne);
            memcpy(&t_Grilles[inc], grille, sizeof(Grille));

            inc++;
          }
       }
    }

    free(ligne);
    free(grille);
    fclose(fdParam);
}

and call it by

chargerGrilles(fichierPar, t_Grilles, sizeof(t_Grilles)/sizeof(t_Grilles[0]));

As you can see I also added check for mallocated variable. You always have to check malloc return value. Otherwise you can invoke Undefined Behavior.

Finally you must free mallocated memory or you will see memory leaks.

Upvotes: 2

Related Questions