Hi all,
Apologies for covering old ground AGAIN... I'm having trouble with a 2D array, pointers, malloc and free (a classic combo). I'm getting a variety of core dumps when running the code below... can anyone spot the problem?
The core dumps are for reasons such as: "free(): invalid next size (fast)". So I guess I'm freeing something I shouldn't be, or corrupting something with overflow. Help!
Firstly, I have declared the structures in my software as follows:
Code:
typedef struct waitingtype {
char* sym_name;
char* bulk_name;
char** alloc_names;
int alloc_count;
} port_wait_struct;
typedef struct maptype {
port_wait_struct** waiting_ports;
int waiting_count;
/* Other stuff here, removed to avoid confusion */
} global_structure;
I am creating the initial pointer as follows:
Code:
global_structure* bulks;
bulks = (global_structure*)malloc(sizeof(global_structure));
bulks->waiting_ports = NULL;
bulks->waiting_count = 0;
The problematic code follows (by the time I get here, I have char arrays param1, param2 and param3 which are all less than 256 characters and are null terminated) :
Code:
int found=-1;
for( int i=0; i<bulks->waiting_count; i++ )
{
if( strcmp( bulks->waiting_ports[i]->bulk_name, param1 ) == 0 )
{
found = i;
}
}
if( found == -1 )
{
found = bulks->waiting_count;
port_wait_struct** new_struct = (port_wait_struct**)malloc( found * sizeof(port_wait_struct*) );
// Only copy old values across if there were any
if( bulks->waiting_count > 0 )
{
for( int i=0; i<bulks->waiting_count; i++ )
{
new_struct[i] = bulks->waiting_ports[i];
}
}
// Put our new value on the end.
new_struct[found] = (port_wait_struct*)malloc( sizeof( port_wait_struct ) );
new_struct[found]->bulk_name = (char*)malloc( 256 * sizeof(char) );
new_struct[found]->sym_name = (char*)malloc( 256 * sizeof(char) );
strncpy( new_struct[found]->bulk_name, param1, 256 );
new_struct[found]->bulk_name[256 - 1] = '\0';
strncpy( new_struct[found]->sym_name, param3, 256 );
new_struct[found]->sym_name[256 - 1] = '\0';
new_struct[found]->alloc_count = 0;
new_struct[found]->alloc_names = NULL;
// Free old one and put our new one in its place.
if( bulks->waiting_ports NEQ NULL )
{
free( bulks->waiting_ports );
}
bulks->waiting_ports = new_struct;
bulks->waiting_count++;
}
// By here we have a 'found' value, whether it's a new one or an
// old one. We need to add ourselves onto the list of names.
int old_count = bulks->waiting_ports[found]->alloc_count;
char** new_names = (char**)malloc( (old_count+1) * sizeof(char*) );
// Copy old ones across if there were any.
if( old_count > 0 )
{
for( int i=0; i<old_count; i++ )
{
new_names[i] = bulks->waiting_ports[found]->alloc_names[i];
}
}
new_names[old_count] = (char*)malloc( 256 * sizeof(char) );
strcpy( new_names[old_count], param2 );
free( bulks->waiting_ports[found]->alloc_names );
bulks->waiting_ports[found]->alloc_names = new_names;
bulks->waiting_ports[found]->alloc_count++;
It's supposed to be an implementation of a map of char-arrays to 'lists' of other char-arrays. param1 is the 'key' and param2 is the char-array to be stored in the 'list'. param3 is kind of irrelevent, but needs to be stored beside the 'key'.
It core dumps if I run the problematic chunk as a function with a whole bunch of test data, and it varies how far through the test data I get.
Help! Much appreciated!