First of all,
a = malloc(sizeof(user) * user_counts);
has a problem - you want to allocate user_counts instances of pointers to user, not instances of user, so that line should be
a = malloc(sizeof(user *) * user_counts);
However, there's an easier way around this - the sizeof operator can take expressions as arguments as well as type names. So you can rewrite that line as
a = malloc( sizeof *a * user_counts );
The expression *a has type user *, so sizeof *a is equivalent to sizeof (user *). This makes your life a bit simpler, in that you don't have to puzzle out the type that a points to - make the compiler do the hard work.
You should always check the result of a malloc call.
a = malloc( sizeof *a * users_count );
if ( a )
{
// do stuff with a
}
Second of all, don't use *(a+i) to index into a - use a[i] instead. Makes things a bit easier to read. So,
*(a+i) = malloc(sizeof(user));
(*(a+i))->id = 1;
(*(a+i))->name = malloc(sizeof(char) * 25);
becomes
a[i] = malloc(sizeof *a[i]);
if ( a[i] )
{
a[i]->id = 1;
a[i]->name = malloc(sizeof *a[i]->name * 25);
}
else
{
/* deal with memory allocation failure */
}
Now, to your actual problem. Your code is crashing for one of the following reasons:
- the initial
malloc of a failed, so you're crashing on the first line that uses a[i];
- the
malloc of one of your a[i] failed, so you're crashing on a[i]->id = 1;
- you've successfully allocated memory for all
users_count elements of a - no a[i] is NULL, so you loop past the last element of your array and try to dereference the object immediately following it, which is most likely not a valid pointer.
In addition to adding the checks after each malloc call, you should probably loop based on users_count:
for ( i = 0; i < users_count; i++ )
printf("ID: %d \t %s\n", a[i]->id, a[i]->name);
Or, you need to allocate one extra element for a and set it to NULL:
a = malloc( sizeof *a * (users_count + 1) );
if ( a )
{
a[users_count] = NULL;
for ( i = 0; i < users_count; i++ )
...
}
Note that calloc initializes all allocated memory to 0, so you can use that and not worry about explicitly setting an element to NULL:
a = calloc( users_count + 1, sizeof *a );
if ( a )
{
for ( i = 0; i < users_count; i++ )
...
}
a = malloc(sizeof(user) * user_counts);is wrong.*ais auser *, not auser.strncpy. Ever.*(a+i)is usually writtena[i].sizeofargument inmalloc().