分配的变量无法访问

时间:2016-07-06 08:36:53

标签: c memory-management

我正在编写一个脚本,这意味着在将文本转换为pdf文件之前将文本放在PostScript文件的末尾。

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);

工作并没有就此止步,但我在这一点上阻止了 这是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);
}

我的结构声明是:

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;

在gdb中我可以打印"来源","扩展"," fichierPar",' numeroFolio"和" typeFolio"就在充电器之前召唤Gigril(fichierPar,t_Grilles);之后,它无法访问。

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>

如果我把手表放在numeroFolio上,gdb就会停在这一行:

t_Grilles[inc] = *grille;

分配的内存怎么了?为什么变量&#39;地址改变?

PS:不要照顾很多printf / fflush,我试图找出segFault的位置

1 个答案:

答案 0 :(得分:2)

您遇到的问题可能是由于t_Grilles数组超出chargerGrilles函数范围而导致的。使用index > NBGRILLE访问它会调用Undefined Behavior,在您的情况下,会损坏其他主要的本地范围变量。

您必须确保循环while(fgets(ligne, 100, fdParam))处理t_Grilles大小。

所以解决方案可以是:

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

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

        inc++;
    }
}

从我的观点来看,最好是添加一个参数来传递数组大小。

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);
}

并通过

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

如您所见,我还添加了对malloc变量的检查。您始终必须检查malloc返回值。否则,您可以调用Undefined Behavior

最后你必须free malloc内存,否则你会看到内存泄漏。