Reputation: 1142
I have this struct i created called User which stores all kind of data, now i'm trying to create an array of it (User*) and get data from a file, this is what i do in the start of my main program:
int amount = 0;
User* users = NULL;
// read from file functions
loadUsers(&users,&amount);
And the function (the amount of users is the first line of my txt file):
void loadUsers(User** users,int* amount2){
int amount, i = 0, j;
char temp[STRING_SIZE], temp2[STRING_SIZE];
FILE* f;
f = fopen("input.txt", "r");
if (!f){
return;
}
if (fileEmpty(f)){
return;
}
fscanf(f, "%d", &amount);
*amount2 = amount;
*users = malloc(sizeof(User)*amount);
/**users = (User*)malloc(sizeof(User)*amount);*/
while (!feof(f)){
fscanf(f, "%s", temp);
users[i]->ID = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->ID, temp);
fscanf(f, "%s", temp);
users[i]->f_name = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->f_name, temp);
fscanf(f, "%s", temp);
users[i]->l_name = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->l_name, temp);
i++;
}
For some reason i get an error and while debugging i see the allocation is wrong since i only have users[0]
and not users[1]
, like an array of users should have, even when the amount is higher than 1.
My target is to have an array, which each cell of it is a User.
What could be the reason?
Edit: User struct:
struct User{
char* ID;
char* f_name;
char* l_name;
int age;
char gender;
char* username;
char* password;
char* description;
char** hobbies;
}typedef User;
Upvotes: 0
Views: 70
Reputation: 34583
Syntax error over the double pointer. Instead of this:
users[i]->ID = (char*)malloc(sizeof(char)*(strlen(temp) + 1));
strcpy(users[i]->ID, temp);
Try this:
(*users)[i].ID = malloc(strlen(temp) + 1);
strcpy ((*users)[i].ID, temp);
And so on for the other fields.
Upvotes: 0
Reputation: 53036
You might be invoking undefined behavior because you don't check for i < amount
in the while loop, you also don't check for fscanf()
to see if it did succesfully read the data, if it fails, tha contents of the temp
array would be uninitialized and trying to copy them to the malloc
ed poitners is Undefined Behavior too.
So your problem is basically that your program is blindly assuming that everything is working as expected and potentially invoking Undefined Behavior, that mistake is very commong among new programmers.
You are allocating space for amount
structs of User
and yet you try to initialize amount
pointers of User
in the for loop, you should dereference the double pointer for it to work properly.
This is your own code with some checks that will prevent undefined behavior
void loadUsers(User** userlist, int* amount2)
{
int amount, i = 0;
char id[100];
char fname[100];
char lname[100];
FILE *file;
User *users;
file = fopen("input.txt", "r");
if (!file) {
return;
}
if (fileEmpty(file)) {
fclose(file);
return;
}
if (fscanf(file, "%d", &amount) != 1)
{
fclose(file);
return;
}
*amount2 = amount;
*userlist = malloc(sizeof(User) * amount);
if (*userlist == NULL)
return; /* malloc can fail, check that */
/* point to the destination pointer to prevent the need of (*users)[i] */
users = *userlist;
/* if fscanf() returns 3 it means that all the arguments where read */
while ((i < amount) && (fscanf(file, "%99s%99s%99s", id, fname, lname) == 3)) {
size_t length;
length = strlen(id);
users[i].ID = malloc(length + 1); /* sizeof(char) == 1 */
if (users[i].ID != NULL)
strcpy(users[i].ID, id);
length = strlen(fname);
users[i].f_name = malloc(length + 1); /* sizeof(char) == 1 */
if (users[i].f_name != NULL)
strcpy(users[i].f_name, fname);
length = strlen(lname);
users[i].l_name = malloc(length + 1); /* sizeof(char) == 1 */
if (users[i].l_name != NULL)
strcpy(users[i].l_name, lname);
i++;
}
fclose(file);
}
Upvotes: 2