2017-10-20 13 views
-3

Code et exemple de fichier csv ci-dessous.pourquoi 2 chaînes différentes ont la même adresse dans C?

Le programme que j'écris est un lecteur csv. Dans la boucle while j'acquiers la ligne du fichier sous forme de chaîne puis avec sscanf j'extrais les données que je stocke dans les variables locales.

J'ai 2 cordes que je stocke en char * nom et prénom char *, mais il leur arrive d'avoir la même adresse:

Printing description of name: 
(char *) name = 0x000000010004da78 "Bob" 
Printing description of surname: 
(char *) surname = 0x000000010004da78 "Bob 

Je ne comprends pas pourquoi, car ils ont des noms de variables.

J'espérais avoir une réponse à cette question, mais ce ne fut pas mon problème: Temporary C strings have same address

Je rebaptisés les variables et Reconstruire le .exe (en utilisant Xcode) mais le problème demeure. Une idée de pourquoi ce problème se produit?

Merci

code

void readFileTest(FILE* *pFile, TTest* *pRootTest) 
//Reads the content of the file, line by line 
{ 
    int count=0; 
    char string[MAX_SIZE]; 
    TTest *pTestCurrent=NULL, *pPrevious=NULL; 

    //Reads first line (wich is the label line) 
    fgets(string, MAX_SIZE, *pFile); 
    printf("Column labelling : %s\n", string); 

    //allocating pointer 
    pTestCurrent=malloc(sizeof(TTest)); 
    pTestCurrent->ID=0; 
    pTestCurrent->name=""; 
    pTestCurrent->surname=""; 
    pTestCurrent->mean=0.0; 
    pTestCurrent->pNext=NULL; 
    pTestCurrent->pPrevious=NULL; 

    (*pRootTest)=pTestCurrent; 
    pPrevious=pTestCurrent; 

    //Extracts data of each line and stores it in a node 
    while(fgets(string, MAX_SIZE, *pFile)) //reads line by line until the EOF 
    { 
     int identification=0; 
     char* name; 
     char* surname; 
     float mean=0.0; 

     //Counts iterations (lines) in the file 
     count+=1; 
     printf("Iteration n°%d\n", count); 

     //Extracts data of the line in variables 
     sscanf(string, "%d,%[^,],%[^,],%f", &identification, name, surname, &mean); 

     //Assign data in variables to node in pTestCurrent 
     pTestCurrent->ID=identification; 
     pTestCurrent->name=name; 
     pTestCurrent->surname=surname; 
     pTestCurrent->mean=mean; 

     //Displays data in node 
     printf("Line content (stored in pTestCurrent) :\nID : %d\nNAME : %s\nSURNAME : %s\nMEAN : %f\n\n", pTestCurrent->ID, pTestCurrent->name, pTestCurrent->surname, pTestCurrent->mean); 

     if(pTestCurrent==NULL) 
     { 
      printf("ERROR : pointer pTestCurrent is NULL, the programm will exit now\n"); 
      EXIT_FAILURE; 
    } 

     //Refresh pointer 
     pTestCurrent->pNext=malloc(sizeof(TTest)); 
     pTestCurrent=pTestCurrent->pNext; 
     pTestCurrent->pPrevious=pPrevious; 
     pTestCurrent->pNext=NULL; 
     pPrevious=pTestCurrent; 
     } 
}; 

fichier Exemple:

ID,NAME,SURNAME,MEAN 
1,Smith,Bob,4.32 
2,Mason,Jack,9.21 
3,Gabe,John,2.67 

Répondre

1

Vous faire deux erreurs:

  1. vous ne disposez pas de mémoire valide lorsque vous sscanf

  2. vous ne copiez pas les valeurs numérisées.

La première:.

sscanf(string, "%d,%[^,],%[^,],%f", &identification, name, surname, &mean); 

ici name et surname sont des pointeurs seulement à char, mais ils ne pointent pas vers la mémoire de votre programme (ils sont uninitalized et peuvent pointer partout où il aurait été probablement vous avez une faute de segmentation). Au lieu, faire:

char name[64], surname[64]; // or any proper size for the names 

Vous avez maintenant la mémoire valide pour votre sscanf. Deuxièmement, lorsque vous copiez les données analysées dans votre structure, vous devez avoir alloué de la mémoire dans votre structure pour les données. Avec seulement pTestCurrent->name=name; vous placez le pointeur à name dans le champ de nom de votre structure, mais vous ne copiez pas les données. Par conséquent, lors de votre prochain sscanf, vous écraserez simplement les données.Au lieu de faire, faire:

pTestCurrent->name= malloc(strlen(name)+1); 
    strcpy(pTestCurrent->name, name); 
2

Le problème ici est, à l'intérieur de la boucle while, vous utilisez le pointeur non initialisée. Ces pointeurs ne sont pas garantis pour pointer valide, et vous essayez d'accéder au pointeur de l'emplacement de mémoire par eux. Cela provoque undefined behavior

Solution: avant de les passer en argument à sscanf(), vous devez vous assurer qu'ils pointent vers une mémoire valide à laquelle votre processus peut accéder.

+0

C'est encore pire car il n'y a pas de mémoire allouée mais accessible. C'est juste une mauvaise connaissance des bases du langage C. –

+0

Les initialiser n'aidera pas s'il continue à "copier" des chaînes de cette façon. – Leeor