0

Having had issues with a slightly more complicated section of code, I've stripped away at it, but still the error remains. Could you cast a cursory eye over this and point out my errors?

//before this, nbnoeud is defined and graphe is a stream that reads from a .txt file

double* xtab = (double *) calloc(nbnoeud, sizeof(double));
double* ytab = (double *) calloc(nbnoeud, sizeof(double));
char** nomtab = (char **) calloc(nbnoeud, 100*sizeof(char));

double x, y; char nom[100]; int numero=0, scancheck;

int a;
for(a=0; a<nbnoeud; a++){
    scancheck = fscanf(graphe, "%d %lf %lf %[^\n]", &numero, &x, &y, nom);
    if(scancheck = 4) printf("Read item %d; \t Scancheck: %d; \t %s - (%lf, %lf). \n", numero, scancheck, nom, x, y);
    xtab[a] = x; 
    ytab[a] = y;
    nomtab[a] = nom; I imagine it's something to do with compatibility of this but to my eyes it all checks out
    /*int b; //this section just illustrates that only the previously accessed elements are being overwritten. See code2.png
    for(b=0; b<=nbnoeud; b++){
        printf("%s \n", nomtab[b]);
    }*/
}

for(a=0; a<nbnoeud; a++){
    printf("Read item %d; \t \t \t %s - (%lf, %lf). \n", a, nomtab[a], xtab[a], ytab[a]);
}

exit(1);

The issue arises when I come to print nomtab[0] through [7] (nbnoeud = 8, in this case), as all values (nomtab[0], nomtab[1], etc.) are equal to the final value that was written. Bizarrely, having checked it, only the already accessed elements of nomtab are overwritten. For example, after the first loop, nomtab[0]= Aaa and the rest equal null; after the second loop, nomtab[0] & nomtab[1] = Baa and the rest equal null (see second image). I imagine there is moronically simple resolution for this but that makes the not-knowing all the more intolerable.

I've also tried using strcpy and it didn't like that.

Any ideas?

Output:

Output:

Output with check of array contents after each loop

Output with check of array contents after each loop

999k
  • 6,257
  • 2
  • 29
  • 32
freewilly
  • 3
  • 1

1 Answers1

2

The problem lies within your line

nomtab[a] = nom;

This sets the pointer at nomtab[a] to point to the local array nom. But with each loop iteration you are overwriting nom when reading the file Input with fscanf. If you want to store all strings, you should make a copy of nom and store that. You can use strdup(nom) to make a copy of nom.

BTW, you are calling fscanf without limiting the number of characters to write into nom. This is a bad idea. If there is a line in the file that is too long, then you will have a buffer overflow in nom, overwriting your stack.

Edit: This line looks suspicous:

char** nomtab = (char **) calloc(nbnoeud, 100*sizeof(char));

I guess, what you want is an array with nbnoeud strings of 100 chars length. You should change that to either

char* nomtab = (char *) calloc(nbnoeud, 100*sizeof(char));
strcpy(nomtab[100*a], nom);

or

char** nomtab = (char **) calloc(nbnoeud, sizeof(char*));
nomtab[a] = strdup(nom);

In the first case nomtab is a big buffer containing all strings (characters), in the second case nomtab is an array of pointers to strings, each one being allocated some other way. In the second case you need to take care to free() the allocated string buffers.

Werner Henze
  • 16,404
  • 12
  • 44
  • 69