![]() |
| |||||||
![]() |
| | LinkBack | Thread Tools | Display Modes |
| | #1 |
| null Join Date: Dec 2005
Posts: 18
| Struct with a ptr to a dynamically allocated array of other structures :( Code: struct Country
{
int continent;
char * name;
char * cap;
char * lang;
};
struct Database
{
struct Country * list;
int ncountries;
char * filename;
};
Code: //insert_database: insert ctry into the right element of db list
void insert_database( struct Database * db, struct Country * ctry )
{
int insertAt;
if( db != NULL && ctry != NULL )
{
for( int i = 0, insertAt = 0; i < db->ncountries; i++ )
{
if( db[i].list == NULL )
{
insertAt = i;
printf( "Insert here: %d\n", insertAt );
//copy_country( db, ctry, i );
break;
}
}
}
}
|
| michael- is offline | |
| | #2 |
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 11,238
| What error message do you get?
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way |
| laserlight is offline | |
| | #3 |
| null Join Date: Dec 2005
Posts: 18
| I don't get one. It inserts one country at index 2, and then it stops (I have 4 countries to be inserted). |
| michael- is offline | |
| | #4 |
| +++ OK NO CARRIER Join Date: Oct 2001
Posts: 10,615
| So are you actually initializing the items you allocate to have NULL pointers, or are you just praying they randomly have that value? Quzah.
__________________ Hundreds of thousands of dipshits can't be wrong. Are you up for the suck? |
| quzah is offline | |
| | #5 |
| null Join Date: Dec 2005
Posts: 18
| Well, that's where I'm stuck. I dynamically allocate (with calloc) the space needed for my array of country structures: Code: db->list = (struct Country *)calloc( countries, sizeof( struct Country ) ); |
| michael- is offline | |
| | #6 |
| null Join Date: Dec 2005
Posts: 18
| Some of the code provided by my teacher makes me doubt what I'm doing (not that I was ever sure): Code: for( i = 0; i < db->ncountries; i++ )
{
delete_country( db->list+i ); // free mem alloc to a country
}
Data structures are so much easier, but I'm stuck with these parameters! |
| michael- is offline | |
| | #7 | |
| Registered User Join Date: Nov 2005
Posts: 95
| Quote:
to loop the array : Code: int i;
for( i = 0; i < db->ncountries; i++ )
db->list[i] = NULL;
/* or
*(db->list+i) = NULL;
*/
Why don't u post the all code ? | |
| dude543 is offline | |
| | #8 |
| +++ OK NO CARRIER Join Date: Oct 2001
Posts: 10,615
| Zero does not necessarily equate a NULL. Quzah.
__________________ Hundreds of thousands of dipshits can't be wrong. Are you up for the suck? |
| quzah is offline | |
| | #9 |
| null Join Date: Dec 2005
Posts: 18
| Hi, I know this is late, but it's on this same topic. Your assistance so far has been really great. I'm stuck on validating the "location-to-insert" in the list. Here's what I have: Code: //insert_database: insert ctry into the right element of db list
void insert_database( struct Database * db, struct Country * ctry )
{
int i, insertAt = 0;
if( db != NULL && ctry != NULL )
{
for( i = 0; i < db->ncountries; i++ )
{
if( /*validate location*/ )
insertAt = i;
}
//printf( "Insert at: %d\n", insertAt );
copy_country( db, ctry, insertAt );
}
}
Code: #include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
struct Country
{
int continent;
char * name;
char * cap;
char * lang;
};
struct Database
{
struct Country * list;
int ncountries;
char * filename;
};
/***** Function Prototypes *****/
struct Database * init_database( char filename[] );
void fill_database( struct Database * db );
struct Country * init_country( int continent, char * name, char * capital, char * languages );
void insert_database( struct Database * db, struct Country * ctry );
void copy_country( struct Database * db, struct Country * ctry, int elem );
void print_database( struct Database * db );
void print_country( struct Country * country );
void delete_database( struct Database * db );
void delete_country( struct Country * ctry );
void FileHandlingFailed( const char * filename );
/***** Function Definitions *****/
int main()
{
struct Database * db;
if( (db = init_database( "lab.txt" )) != NULL )
{
fill_database( db );
//print_database( db );
//delete_database( db );
//free( db );
}
else
{
printf( "Memory allocation procedure failed. Application closing...\n\n" );
return 1;
}
return 0;
}
//init_database: initialize the Database struct
struct Database * init_database( char filename[] )
{
FILE * input;
struct Database * db;
int countries = 0, i;
char c;
if( (input = fopen( filename, "r" )) != NULL )
{
while( (c = fgetc( input )) != EOF )
{
if( c == '\n' )
countries++;
}
db = (struct Database *)malloc( (countries * sizeof( struct Country )) );
if( db != NULL )
{
db->list = (struct Country *)calloc( countries, sizeof( struct Country ) );
if( db->list != NULL )
{
db->ncountries = countries;
db->filename = filename;
}
}
fclose( input );
}
else
{
FileHandlingFailed( filename );
return NULL;
}
return db;
}
//fill_database: fills the Database country list with stuff from file
void fill_database( struct Database * db )
{
FILE * input;
struct Country * tempCtry;
int cont;
char name[81], capital[81], lang[81];
char c;
if( (input = fopen( db->filename, "r" )) != NULL )
{
while( fscanf( input, "%d,%[^,],%[^,],%[^\n]", &cont, name, capital, lang ) != EOF )
{
if( (tempCtry = init_country( cont, name, capital, lang )) != NULL )
insert_database( db, tempCtry );
else
{
printf( "Memory allocation failed in init_country function. Aborting...\n" );
break;
}
}
fclose( input );
}
else
{
FileHandlingFailed( db->filename );
return;
}
}
//init_country: allocates memory for a new Country structure and its contents
struct Country * init_country( int continent, char * name, char * capital, char * languages )
{
struct Country * ctryStruct;
ctryStruct = (struct Country *)malloc( sizeof( struct Country ) );
if( ctryStruct != NULL )
{
//country continent
ctryStruct->continent = continent;
//init name ptr
ctryStruct->name = (char *)calloc( strlen( name ) + 1, sizeof( char ) );
if( ctryStruct->name != NULL )
{
//copy in ctry name
strcpy( ctryStruct->name, name );
//init cap ptr
ctryStruct->cap = (char *)calloc( strlen( capital ) + 1, sizeof( char ) );
if( ctryStruct->cap != NULL )
{
//copy in ctry capital
strcpy( ctryStruct->cap, capital );
//init lang ptr
ctryStruct->lang = (char *)calloc( strlen( languages ) + 1, sizeof( char ) );
if( ctryStruct->lang != NULL )
{
//copy in ctry languages
strcpy( ctryStruct->lang, languages );
//printf( "%d, %s, %s, %s\n", ctryStruct->continent, ctryStruct->name, ctryStruct->cap, ctryStruct->lang );
}
else
{
free( ctryStruct->cap );
free( ctryStruct->name );
free( ctryStruct );
ctryStruct = NULL;
}
}
else
{
free( ctryStruct->name );
free( ctryStruct );
ctryStruct = NULL;
}
}
else
{
free( ctryStruct );
ctryStruct = NULL;
}
}
return ctryStruct;
}
//insert_database: insert ctry into the right element of db list
void insert_database( struct Database * db, struct Country * ctry )
{
int i, insertAt = 0;
if( db != NULL && ctry != NULL )
{
for( i = 0; i < db->ncountries; i++ )
{
if( /*validate location*/ )
insertAt = i;
}
//printf( "Insert at: %d\n", insertAt );
copy_country( db, ctry, insertAt );
}
}
//copy_country: performs insertion of the ctry struct into the db list
void copy_country( struct Database * db, struct Country * ctry, int elem )
{
db->list[elem] = *ctry;
}
//print_database: prints all the Countries
void print_database( struct Database * db )
{
int i;
for( i = 0; i < db->ncountries; i++ )
{
print_country( db->list+i );
}
printf( "Total countries: %d\n", db->ncountries );
return;
}
//delete_database: frees allocated memory in array of Countries
void delete_database( struct Database * db )
{
int i;
for( i = 0; i < db->ncountries; i++ )
{
delete_country( db->list+i ); // free mem alloc to a country
}
free( db->list ); // free array
free( db->filename );
}
//delete_country: frees memory for Country structures
void delete_country( struct Country * ctry )
{
free( ctry->name );
free( ctry->cap );
free( ctry->lang );
}
//print_country: prints a Country structure
void print_country( struct Country * country )
{
printf("%-23s%-20s%-25s\n", country->name, country->cap, country->lang );
}
//FileHandlingFailed: prints the error msg when program fails to load file
void FileHandlingFailed( const char * filename )
{
printf( "File handling procedure failed: unable to locate file %s. Application closing...\n\n", filename );
}
|
| michael- is offline | |
| | #10 |
| +++ OK NO CARRIER Join Date: Oct 2001
Posts: 10,615
| db->list[ x ] is the instance of a structure. You are, by using [ ], dereferencing the pointer, to give you the structure itself. You cannot see if a structure is null. You have to check to see if the pointer to the structure is null. Perhaps you should change list to be an array of pointers to structures instead. [edit] There's really no way to do what you're asking easily. If all you have is a pointer to a series of objects, there is no way to know when you reach the end of those objects, unless they have speficically allocated an extra pointer, and set it to null. Even that is painful to attempt. Basically you need, not a pointer to an object, but a pointer to a pointer to an object. If that turns up NULL, then you have a pointer which doesn't point to an object. There is no way to allocate a block of N objects, and have the "N+1" object be null. Malloc won't do it. What it sounds like you want is a "string" of objects, where the final one is the null character. Well, consider strings. Even if you encounter a 'null character', that is still an instance of a character. It's just a character you use to compare against to stop your looping. It would be the same as if you had chosen the letter 'a' to stop on. There is still a character there. You can't run through a string and stop when you reach a character that isn't there, because as far as it's concerned, there's always a character there. You just pick some value to stop on. Basically, you create enough room to set one character to "null", and stop when you reach it. You will need to have done the same thing with your array of structures. Have one more on the end always set to some value, and stop when you find it. The best you could get would be something like: Code: int checknull( struct list *l )
{
if( l->contient == foo && l->name == NULL && l->cap == NULL && l->lang == NULL )
return at_the_end_value;
return not_at_the_end_value;
}
[/edit] Quzah.
__________________ Hundreds of thousands of dipshits can't be wrong. Are you up for the suck? Last edited by quzah; 05-18-2006 at 11:11 PM. |
| quzah is offline | |
| | #11 |
| null Join Date: Dec 2005
Posts: 18
| Thanks Quzah. That really really helps. I rewrote my insert_database function, implementing what you suggested. Here's what I ended up with: Code: void insert_database( struct Database * db, struct Country * ctry )
{
int i, insertAt = -1;
struct Country * elem;
if( db != NULL && ctry != NULL )
{
for( i = 0; i < db->ncountries && insertAt < 0; i++ )
{
if( (db->list+i)->continent == 0 )
{
elem = db->list+i;
insertAt = i;
}
}
copy_country( elem, ctry );
}
}
|
| michael- is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| allocation and reallocation of memory dynamically of an integer array | zamir | C++ Programming | 16 | 05-29-2009 07:25 PM |
| Help calling function is asm | brietje698 | C++ Programming | 24 | 12-06-2007 04:48 PM |
| Help with dynamically allocated array of pointer to a structure. | cmasri | C++ Programming | 6 | 01-16-2007 09:21 PM |
| Unknown Memory Leak in Init() Function | CodeHacker | Windows Programming | 3 | 07-09-2004 09:54 AM |
| Hi, could someone help me with arrays? | goodn | C Programming | 20 | 10-18-2001 09:48 AM |