As homework, I have to write a function that changes an array's size using malloc
and free
functions only.
I know how to do it with realloc
, but I don't know how to do it with malloc
.
typedef struct{
int *tab;
int size;
}arr;
and I need to write this function :
void changeSizeDyn(arr *Dyn_arr, int size){
//
}
As mentioned in the homework: it requires only one reallocation and only one memory release, and only one copy of the elements from the old array.
I searched a lot but only found results using realloc
.
Is it even possible to do that without using realloc
?
struct Arr {
int *tab;
ptrdiff_t nmemb;
};
Let's say you allocated the array like this initially:
struct Arr x;
x.nmemb = 7;
x.tab = malloc(sizeof(*x.tab) * x.nmemb);
You should realloc it with this function:
void change_size_dyn(struct Arr *dyn_arr, ptrdiff_t nmemb)
{
struct Arr old;
ptrdiff_t cp_nmemb;
if (!dyn_arr)
return;
old = *dyn_arr;
if (nmemb <= 0)
goto err;
dyn_arr->tab = malloc(sizeof(*dyn_arr->tab) * nmemb);
dyn_arr->nmemb = nmemb;
cp_sz = MIN(old.nmemb, nmemb);
memcpy(dyn_arr->tab, old.tab, cp_nmemb);
free(old.tab);
return;
err:
dyn_arr->tab = NULL;
dyn_arr->nmemb = 0;
free(old.tab);
}
Which should be called this way:
change_size_dyn(&x, 9);
You can use this function even for the first allocation (although you should set to NULL
and 0
both values first). You also don't need to add a free; an input of 0 would do it for you, just like realloc
would do:
int main(void)
{
struct Arr x = {0};
change_size_dyn(&x, 5);
/* ... */
change_size_dyn(&x, 9);
/* ... */
cleanup:
change_size_dyn(&x, 0);
return 0;
}
If you pass a structure where dyn_arr->nmemb
is already a negative value (shouldn't happen), the behaviour is undefined (that negative value would go into memcpy
, which would be wrapped into a very high size_t
, which would overflow the arrays). I didn't want to check for that because it would be unnecessary in any non-buggy scenario.