Reputation: 51
I am passing a struct through a function like so...
expandArrayofStructs(Container *container, int n)
This container is one struct and inside of that struct is an array of another type of struct I'll call it inner.
I would like to expand the size of the array of inner by some value and then continue in my original function after the array has been expanded. So this expand function does not return anything rather it is just called and expands the data and finishes and the program continues with a new larger array than before.
My understanding of the situation would be something like this but this does not work properly...
int expandArrayofStructs(Container *container, int n)
{
container->inner = realloc(container->inner, sizeof(inner) * 50);
^
Just a number i picked. so if i
already had an array of 50
I would be increasing by 50 here.
if(Container->inner == NULL)
//HANDLE ERROR IF REALLOC FAILS
//Update the container length
container->length = container->length + 50;
//For some reason the specs of the program say I need to return
//the array length which is an attribute of container
return container->length;
}
But when I realloc in this manner I am not even getting segfault error I am getting: realloc(): invalid next size 0x463829
the numbers at the end vary.
Not sure what I am doing wrong, but if there is a better way to dynamically realloc an array of structs then I am open to suggestion. This particular code does not have to be exactly what it is.
The only stipulation is that this function returns type int which is = the new array length
Upvotes: 0
Views: 3150
Reputation: 59997
Why not read the manual page (see http://linux.die.net/man/3/realloc). You are using the same size each time. Besides - Why not use a linked list?
Upvotes: 0
Reputation: 3607
You have to allocate new memory, and you don't do that.
int expandArrayofStructs(Container *container, int n)
{
container->inner = realloc(container->inner, sizeof(inner) * (50 + container->length));
if(Container->inner == NULL)
/* return -1; (set realloc handle errors properly)*/
container->length = container->length + 50;
return container->length;
}
Upvotes: 0
Reputation: 123448
Assuming your struct definition looks something like this:
typedef struct { ... } Inner;
typedef struct { ...; Inner *inner; size_t length; } Container;
then your function would look something like
size_t expandArrayOfStruct( Container *container, size_t extent )
{
Inner *tmp = realloc( container->inner,
sizeof *container->inner * (container->length + extent) );
if ( tmp )
{
container->length += extent;
container->inner = tmp;
}
return container->length;
}
You want to assign the result of realloc
to a temporary variable; if the operation fails, realloc
will return NULL, and if you assign that to your original pointer you'll lose your reference to the memory that was already allocated, causing a memory leak.
You can use this function for the original allocation as well:
int main( void )
{
Container c = {..., NULL, 0 };
size_t len = expandArrayOfStruct( &c, 50 );
if ( len != 50 )
{
// allocation failed
}
...
}
Upvotes: 0
Reputation: 2828
This error happens because you are not "reallocating" more memory. You are allocating the same the size.
To fix it, just allocating total size that you will need:
container->inner = realloc(container->inner, sizeof(inner) * (50 + container->length);
Upvotes: 2
Reputation: 64308
The new allocated size should be based on the size of the elements of the array, and not based on the size of the pointer to the beginning of the array. Also you want to resize it relative to the current length:
container->inner = realloc(container->inner, sizeof(*container->inner) * (container->length + 50));
Upvotes: 0