2016-07-06 63 views
0

我正在研究一个脚本,它意味着在将文本转换为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” 只是调用之前到chargerGrilles(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; 

分配的内存发生了什么变化?为什么变量的地址会改变?


PS:不要照顾很多的printf/fflush的,这就是我试图找出哪里是段错误

+2

我建议你用英文而不是主语言编写代码,注释和var/names/etc,以后再分享,维护和重用会更容易。对不起,但无关的评论。 – Tim

+1

't_Grilles [inc] = * grille;' - >'memcpy(&t_Grilles [inc],grille,sizeof(Grille));' – LPs

+1

你确定'inc LPs

回答

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 ated变量还增加了检查。你总是要检查malloc返回值。否则,您可以调用Undefined Behavior

最后你必须freemalloc ated内存或你会看到内存泄漏。

+0

'memcpy'是不必要的。 OP正在执行直接结构分配,这在C中得到了支持。另一方面,“grille”和“ligne”的动态分配首先毫无意义;两个都比简单的当地人更合理。 – WhozCraig

+0

@WhozCraig我没有强调'memcpy'的改变,因为我是为了清晰而做的。我同意,局部变量绰绰有余。 – LPs