this program is to extract the first and last names and whenever a extract the first names correctlly ( or the last names ) the other is changing its value to first ellement of the other's file
so if f1 contains Martin and f2 contains Joseph
when calling
GetPrenom(f2)
the result is
Joseph
but after calling
Getnom(f1)
the result changes to
Martin
this is my code
#include<stdlib.h>
#include<string.h>
#include <stdarg.h>
char* GetNom(FILE* f1) {
char* nam = malloc(25 * sizeof(char));
fseek (f1, 0, SEEK_END);
int length = ftell (f1);
fseek (f1, 0, SEEK_SET);
char line1[length];
fgets(line1, length, f1);
nam = strtok(line1, " , ");
rewind(f1);
return nam ;
}
char* GetPrenom( FILE* f2) {
char* lastname = malloc(25 * sizeof(char));
fseek (f2, 0, SEEK_END);
int length = ftell (f2);
fseek (f2, 0, SEEK_SET);
char line2[length];
fgets(line2, length, f2);
lastname = strtok(line2, " ; ");
rewind(f2);
return lastname ;
}
int main() {
FILE* f1 = ....; //openning the two files
FILE* f2 = ....;
char* prenom = GetPrenom(f2);
char* nom = GetNom(f1);
printf("%s \n", prenom);
return 0;
}
what i expecte as a result is to have Joseph as first name but the result is the first str in f1 file which is Martin
so the pointer is changing its value without even passing by a function
CodePudding user response:
char* nam = malloc(25 * sizeof(char));
...
nam = strtok(line1, " , ");
is a memory leak, the initialized value is overwritten with the address of a local array. Dereferencing or trying to read this local array in main
is UB. That's why you get odd results.
You can fill nam
directly, something like:
fseek (f1, 0, SEEK_END);
long length = ftell(f1) 1;
fseek (f1, 0, SEEK_SET);
char *nam = malloc(length);
fgets(nam, length, f1);
char *token = strtok(nam, " , ");
rewind(f1);
return token;
Same for GetPrenom
CodePudding user response:
You carefully malloc
-ed buffers, then ignored them and use stack-allocated arrays, and returned (immediately invalid) pointers to those stack arrays.
nam = strtok(line1, " , ");
does not, in any way, use the malloc
ed memory nam
originally pointed to, instead it throws away that pointer (leaking memory) and replaces it with a pointer to the first token within line1
(a pointer that's actually guaranteed to be equivalent to the address of line1
, strtok
just went and mutated the string to cut it off where the first delimiter began).
The second call reused the same part of the stack for its stack-allocated array, stomping all over that memory.
The code was undefined behavior, so count yourself lucky all it did was replace one valid string with another.
What you wanted would be something like:
char* GetNom(FILE* f1) {
fseek(f1, 0, SEEK_END);
int length = ftell(f1);
fseek(f1, 0, SEEK_SET);
char line1[length];
fgets(line1, length, f1);
char *tok = strtok(line1, " , "); // Tokenize to get first token
char *nam = malloc(strlen(tok) 1); // Allocate exact space for first token, plus one for NUL
strcpy(nam, tok); // Copy data from token to malloc-ed buffer
rewind(f1);
return nam; // Return malloc-ed buffer, not pointer into transient line1
}
A similar change would be used for your other function.