2012-12-03 2 views
2

Je comprends, que dans le monde de la programmation, rien ne se passe juste en dehors du bleu, mais je suis vraiment coincé ici ... A la fin de ma boucle while, pointeur à l'intérieur de l'état change brusquement de NULL à « quelque chose »Boucle infinie à cause du changement « soudaine » du pointeur

J'ai la fonction suivante:

tListInstr *copyList (tListInstr *sourceList) { 

    tListInstr *newList; 
    listInit(&newList); 
    listFirst(sourceList); 

    while(sourceList->active != NULL){ 
     InstructionGenerate(newList, 
         sourceList->active->Instruction.instType, 
         sourceList->active->Instruction.addr1, 
         sourceList->active->Instruction.addr2, 
         sourceList->active->Instruction.addr3); 

     listNext(sourceList); 
     if(sourceList->active == NULL) 
      printf("wtf????\n"); 
    } 

    return newList; 
} 

pour exaplain le code, il fait partie d'un interprète, cette fonction copie 3 adresses liste d'instructions de code de fonction appelée dans le langage source et renvoie la copie, sourceList est la liste à copier (ce n'est jamais NULL) newList est la nouvelle liste évidente. listInit alloue la mémoire et initialise nouvelle liste, listFirst ensembles activité de sourceList à son premier article. listNext décale l'activité vers l'élément suivant, juste derrière le courant actif. InstructionGenerate ajoute une nouvelle instruction à newList.

Eh bien, mon problème est, qu'à la fin de la boucle sourceList->active est clairement NULL, parce que je suis wtf???? infinie s sur le terminal, mais après il est imprimé et la condition de while get testé, il a une valeur non NULL (J'ai vérifié) et le temps boucle infiniment.

La partie drôle est que lorsque je retire l'appel InstructionGenerate, il fonctionne Allright. Mais InstructionGenerate ne doit pas/ne doit pas affecter sourceList pointeur de quelque façon que ce soit, car il travaille avec newList et si d'une manière étrange, je ne comprendrais pas faire quelque chose avec sourceList, je change l'activité après qu'elle s'appelle et tester la condition AVANT qu'il soit appelé.

Je ne pense pas que ce sera d'aucune aide, mais voici le code de InstructionGenerate et la fonction qu'il appelle:

void InstructionGenerate(tListInstr *l, int varType,void *addr1, void *addr2,void *addr3){ 
    tInstr I; 
    I.addr1 = addr1; 
    I.addr2 = addr2; 
    I.addr3 = addr3; 
    I.instType = varType; 
    listInstInsert(l,I); 
} 

void listInstInsert(tListInstr *L,tInstr I) 
{ 
    tListItem ptr = malloc(sizeof(struct listItem)); 
    if(ptr == NULL) 
     return; 
    else 
    { 
     ptr->Instruction = I; 
     if (L->first == NULL){ 
      ptr->nextItem = NULL; 
      L->first = ptr; 
      L->end = ptr; 
     } 
     else{ 
      ptr->nextItem = NULL; 
      L->end->nextItem = ptr; 
      L->end = ptr; 
     } 
    } 
} 

Et enfin struct « s

typedef struct tInstr 
{ 
    int instType; 
    void *addr1; 
    void *addr2; 
    void *addr3; 
} tInstr; 

typedef struct listItem 
{ 
    tInstr Instruction; 
    struct listItem *nextItem; 
} *tListItem; 

typedef struct tListInstr 
{ 
    struct listItem *first; 
    struct listItem *end; 
    struct listItem *active; 
} tListInstr; 

Compilé par:
gcc version 4.4.5 (Debian 4.4.5-8)
gcc version 4.5.4 (GCC)

+3

Compilez avec toutes les informations d'avertissement et de débogage, par ex. avec 'gcc -Wall -g' et apprendre à utiliser le débogueur' gdb' (et aussi 'valgrind'). –

+0

compilé avec gcc -Wall -Wextra -pedantic -ggdb std = c99', 'valgrind' ne mettent en garde contre anythign et même avec' gdb' je ne pouvais pas savoir ce qui est arrivé – rivfaader

+0

Utilisez le '' watch' et step' commandes de 'gdb' –

Répondre

1

Vous avez probablement une erreur dans la manipulation de votre pointeur quelque part. Je ne vois aucun appel à libérer, donc vous n'avez probablement pas de problème de pointeur. Vous utilisez probablement un pointeur non initialisé ou utilisez un pointeur d'une manière ou d'une autre. Peut-être pointe-t-il une région valide sur la pile dans une image, et pas dans une autre. Pipelining est ce qui provoque votre «wtf infinie» éloquemment déclaré. Lorsque l'instruction de comparaison dans le if est exécutée, la valeur est NULL. Quand il est à nouveau comparé dans la précondition de la boucle, une modification en pipeline a pris effet en la définissant sur une valeur non NULL.

Questions connexes