User:Pmd.nagarjun/sandbox

Anyways, I figured I might share a few snippets and wisdom that I’ve picked up along the way, so here’s a quick (?) rundown of how to use structs and pointers to create “dynamic” arrays that will resize as you need them. Right, so let’s suppose you’ve got a struct built that you’ll use to hold some data…

typedef struct { char *name; int number; } DATA;

And we’ll also need to set up an array, along with some variables to track how many items are in the array and how large the array is…

DATA   *the_array = NULL; int    num_elements = 0; // Keeps track of the number of elements used int    num_allocated = 0; // This is essentially how large the array is

What’s this? I’m not using []‘s to define the size of the array? That’s right; At this point, the array is just a pointer. We’ll need to allocate memory for each entry into the array. So next, we need a way to add items to our array that will be mindful of the fact that it is dynamic. What is needed is a function that will do three things: Initialize the array if it is not already initialized. Resize the array if more space is needed. Add new items to the array. Keeping that in mind, let’s take a look at the realloc function‘s prototype:

void * realloc ( void * ptr, size_t size );

The purpose of this function is to re-allocate memory to a pointer that already has memory allocated to it. Of course, you’ll only want to use it to make memory allocations larger, otherwise you’ll risk losing data. The size parameter is the amount of memory that you want to allocate. And the other parameter, ptr, is where you’d like to allocate it to. In this case, it’ll be the TheArray pointer that we’ve defined above. What is great about realloc is that if the ptr is NULL, the function will act just like malloc. This will allow us to use this one call for both initializing and resizing the array. Check this realloc reference page for more information. Here is my AddToArray function …

int AddToArray (DATA item) {       if(num_elements == num_allocated) // Are more refs required? {                // Feel free to change the initial number of refs // and the rate at which refs are allocated. if (num_allocated == 0) num_allocated = 3; // Start off with 3 refs else num_allocated *= 2; // Double the number // of refs allocated

// Make the reallocation transactional // by using a temporary variable first void *_tmp = realloc(the_array, (num_allocated * sizeof(DATA)));

// If the reallocation didn't go so well, // inform the user and bail out if (!_tmp) {                       fprintf(stderr, "ERROR: Couldn't realloc memory!\n"); return(-1); }

// Things are looking good so far the_array = (DATA*)_tmp; }

the_array[num_elements] = item; num_elements++;

return num_elements; } You can see that it performs all three requirements listed above. You may ask, ‘why is the allocation size doubling each time a resize is needed?’. This is done mainly because realloc can be an expensive call, and if you spend a lot of time resizing your array, it could slow down the execution of your application. This way, it’s only done once in a while. Of course, feel free to fiddle with the initial allocation as well. Also, be careful when using realloc, as you’ll need to remember to use the free function later on to free the memory that you’ve allocated to your program. You’ll want to run this code when you’re done using the array …

// Deallocate! free(TheArray);

I’ve got a little example available right here:

// Example code from "a tutorial on 'dynamic' arrays in C" // http://fydo.net

// Special thanks for suggestions and help from: //  bbulkow of http://bbulkow.blogspot.com //  tinkertim of http://echoreply.us

// Output: // Steve's number is 42! // Bill's number is 33! // George's number is 15! // fydo's number is 74! // // 6 allocated, 4 used

// This code is public domain. Do whatever you like with it! :D // I've tested it using GCC, no promises for anything else. Sorry.


 * 1) include 
 * 2) include 
 * 3) include 

typedef struct { char *name; int number; } DATA;

DATA 	*the_array = NULL; int 	num_elements = 0; // To keep track of the number of elements used int		num_allocated = 0; // This is essentially how large the array is

int AddToArray (DATA item) {	if(num_elements == num_allocated) { // Are more refs required? // Feel free to change the initial number of refs and the rate at which refs are allocated. if (num_allocated == 0) num_allocated = 3; // Start off with 3 refs else num_allocated *= 2; // Double the number of refs allocated // Make the reallocation transactional by using a temporary variable first void *_tmp = realloc(the_array, (num_allocated * sizeof(DATA))); // If the reallocation didn't go so well, inform the user and bail out if (!_tmp) { 			fprintf(stderr, "ERROR: Couldn't realloc memory!\n"); return(-1); }		// Things are looking good so far, so let's set the the_array = (DATA*)_tmp; }	the_array[num_elements] = item; num_elements++; return num_elements; }

int main {	// Some data that we can play with char *names[4] = { "Steve", "Bill", "George", "fydo" }; int numbers[4] = { 42, 33, 15, 74 }; int i; // Populate! for (i = 0; i < 4; i++) {		DATA temp; temp.name = malloc((strlen(names[i]) + 1) * sizeof(char)); strncpy(temp.name, names[i], strlen(names[i]) + 1); temp.number = numbers[i]; if (AddToArray(temp) == -1) // If there was a problem adding to the array, return 1;				// we'll want to bail out of the program. You // can handle it however you wish. }	// Open a file and ... FILE *out; out = fopen("output.txt", "w"); // Regurgitate! for (i = 0; i < 4; i++) {		fprintf(out, "%s's number is %d!\n", the_array[i].name, the_array[i].number); }	fprintf(out, "\n%d allocated, %d used\n", num_allocated, num_elements); fclose(out); // Deallocate! for (i = 0; i < 4; i++) {		free(the_array[i].name); }

free(the_array); // All done. return 0; }

It compiles and runs just fine using GCC, but I haven’t tried it with anything else, so your mileage may vary. Also, a huge special thanks to DrPetter and X-0ut for their help on this subject!

Source : http://fydo.net/gamedev/dynamic-arrays