C 分配变量不可访问

C 分配变量不可访问,c,memory-management,C,Memory Management,我正在编写一个脚本,这意味着在将PostScript文件转换为pdf文件之前,将文本放在PostScript文件的末尾 int main(int argc, char *argv[]){ // Déclaration des variables // Fichier source char *source; // Extension du fichier source char *extension; // Fichier de parametr

我正在编写一个脚本,这意味着在将PostScript文件转换为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()的代码

这是我的结构声明:

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中,我可以在调用chargerGrilles(fichierPar,t_Grilles)之前打印“source”、“extension”、“fichierPar”、“numeriofolio”和“typeFolio”;之后将无法访问

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>
分配的内存怎么了?为什么变量的地址会改变



PS:不要处理太多的printf/fflush,这是我如何试图找出segFault的位置的问题。您面临的问题可能是由于访问
t_Grilles
数组出界进入
chargerGrilles
函数而引起的。使用
index>nbgrill
访问它会调用并损坏其他主要local作用域变量

必须确保while(fgets(ligne,100,fdParam))循环
while
处理
t_格栅的大小

因此,解决方案可以是:

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

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

        inc++;
    }
}
如您所见,我还添加了检查
malloc
ated变量。您必须始终检查
malloc
返回值。否则,您可以调用


最后,您必须
释放
内存,否则您将看到内存泄漏。

您面临的问题可能是由于访问
t_Grilles
数组出界进入
chargerGrilles
函数而引起的。使用
index>nbgrill
访问它会调用并损坏其他主内存局部作用域变量

必须确保while(fgets(ligne,100,fdParam))循环
while
处理
t_格栅的大小

因此,解决方案可以是:

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

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

        inc++;
    }
}
如您所见,我还添加了检查
malloc
ated变量。您必须始终检查
malloc
返回值。否则,您可以调用


最后,您必须
释放
内存,否则您将看到内存泄漏。

我建议您用英语编写代码、注释和var/names/etc,而不是主语言,这样以后更容易共享、维护和重用。不过,对于不相关的注释,我深表歉意。
t\u Grilles[inc]=*格栅;
-->
memcpy(&t_格栅[inc],格栅,尺寸(格栅))
您确定
inc
?我猜不是,而且您超出了数组的范围,损坏了其他主要的本地作用域变量。@TimF此代码不是要共享的,只是在本例中提供帮助。@Lps…如果文件“fichierPar”“变了。我没有更新值。我恨我自己。谢谢您能否创建一个简短的答案,以便我验证它?我建议您用英语而不是主语言编写代码、注释和var/names/etc,这样以后更易于共享、维护和重用。不过,对于与此无关的评论,我深表歉意。
t_Grilles[inc]=*Grilles-->
memcpy(&t_Grilles[inc],格栅,尺寸(格栅))
您确定
inc
?我猜不是这样的,您超出了数组的范围,损坏了其他主要的本地作用域变量。@TimF此代码不打算共享,只是在本例中用于帮助。@Lps。。。如果文件“fichierPar”发生更改,我会发出一个更新值的警告。我没有更新值。我恨我自己。谢谢你能给我一个简短的答案让我验证一下吗?不需要
memcpy
。OP正在执行直接结构分配,这在C中得到了支持。另一方面,
格栅
直线
的动态分配从一开始就没有什么意义;作为简单的本地人,这两种方法都是合理的。@WhozCraig我没有强调
memcpy
的变化,因为我这样做是为了清晰。我同意,局部变量已经足够了。没有必要使用
memcpy
。OP正在执行直接结构分配,这在C中得到了支持。另一方面,
格栅
直线
的动态分配从一开始就没有什么意义;作为简单的本地人,这两种方法都是合理的。@WhozCraig我没有强调
memcpy
的变化,因为我这样做是为了清晰。我同意,局部变量已经足够了。
 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]));