• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1603
  • Last Modified:

Array of Structs and Realloc

Part of an assignment is to create to .dat files, such as vehicles.dat and rentalsl.dat.  Then, once a file is open, data is read into an array of structs, using the realloc library function to dynamically create sufficient memory for each user entry read from the file.

I've gotten this far, but I'm a bit stuck.  Any help would be appreciated!

void load_data();
{  //**RECEIVE AN ERROR HERE
     int count=0, file_end=0;
             FILE* file_ptr=fopen("vehicles.dat", "r");
             FILE* file_ptr_2=fopen("rentals.dat", "r");
             printf("\n%20s%10s%10s\n", "VEHICLE TYPE", "VEHICLE CLASS", "REGISTRATION");
do
{
          file_end=fscanf(file_ptr, "%s%s%d", temp_vehicle.type, temp_vehicle.cls, &(temp_vehicle.reg));
	if (file_end != EOF)
	{
	printf("\n%20s%10s%10d", temp_vehicle.type, temp_vehicle.cls,  &temp_vehicle.reg);
	count++;
	}
	}
	while (file_end != EOF);
	fclose(file_ptr);
	}

Open in new window

0
clscor2
Asked:
clscor2
  • 4
2 Solutions
 
Kent OlsenData Warehouse Architect / DBACommented:
Hi clscor,

realloc is not the *best* function here, but your instructor may have told you to use it.  malloc() or calloc() is more appropriate as what you want to do is assign memory from the heap, not reassign it.

Within your loop, once you read a line and determine that you want to save it to memory, call malloc() to assign memory for your structure and populate it.  It will look something like this:

typedef struct
{
  // definitions
} mystruct_t;

mystruct_t *Array[100];
mystruct_t *Item;

//  Within the loop, add this:

  Item = (mystruct_t*) malloc (sizeof (mystruct_t));
  Array[count] = Item;


Then, of course, populate the items in the structure.


Good Luck,
Kent

0
 
evilrixSenior Software Engineer (Avast)Commented:
void load_data();        <--------------------------[ Look, you have a semi-colon here that shouldn't be
{  //**RECEIVE AN ERROR HERE
0
 
evilrixSenior Software Engineer (Avast)Commented:
>> realloc is not the *best* function here
Maybe the idea is to grow the array not have a fixed size array. Something like below maybe (untested code alert)?
#include <malloc.h>
#include <memory.h>
 
typedef struct { int nSomeMember; } foo;
 
int ReadFromFile(foo * pFoo) // Just a dummy function to allow the exmaple to build
{
	// Read a record from file and populate the object pointed to by pFoo;
	return 1; // Return false where no more records to process
}
 
int main()
{
	foo * pFoo = 0;
	size_t cnt = 0;
	foo f;
	f.nSomeMember = 0;
 
	while(ReadFromFile(&f))
	{
		pFoo = realloc(pFoo, cnt + 1); // Extend foo array
 
		if(pFoo)
		{
			// add foo to array
			memcpy(&pFoo[cnt], &f, sizeof(f));
		}
		else
		{
			// error
		}
	}
 
	// Now clean up
	free(pFoo);
}

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
evilrixSenior Software Engineer (Avast)Commented:
Oops I forgot to increment cnt :)
#include <malloc.h>
#include <memory.h>
 
typedef struct { int nSomeMember; } foo;
 
int ReadFromFile(foo * pFoo) // Just a dummy function to allow the exmaple to build
{
	// Read a record from file and populate the object pointed to by pFoo;
	return 1; // Return false where no more records to process
}
 
int main()
{
	foo * pFoo = 0;
	size_t cnt = 0;
	foo f;
	f.nSomeMember = 0;
 
	while(ReadFromFile(&f))
	{
		pFoo = realloc(pFoo, cnt + 1); // Extend foo array
 
		if(pFoo)
		{
			// add foo to array
			memcpy(&pFoo[cnt++], &f, sizeof(f));
		}
		else
		{
			// error
		}
	}
 
	// Now clean up
	free(pFoo);
}

Open in new window

0
 
evilrixSenior Software Engineer (Avast)Commented:
>> pFoo = realloc(pFoo, cnt + 1)
Should be
 pFoo = realloc(pFoo, sizeof(Foo) * cnt + 1);

Also... when using realloc you should initally assign the return value to a new pointer and not overwrite the old one (as I have done above). The reason for this is if memory cannot be allocated then realloc returns NULL, but the original memory is not freed so if you just overwrite the original pointer you'll leak memeory.

int * porig = calloc(10, sizeof(int));
int * pnew = realloc(porig, sizeof(int) + 20);
if(pnew) { porig = pnew; }
else { /* problem */ }



0
 
clscor2Author Commented:
Thank you
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now