C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 08-27-2008, 10:33 AM   #1
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,946
Arrow I want a dynamic array.

Based on my last series of posts which you needn't read, I now need a new method of creating a dynamicly expanding global array. I suspect I won't get one, which would be COMPLETELY RIDICULOUS and makes me wonder how anyone has managed to do anything significant in C at all.

Here's the issue: I want to read in a text file consisting of lines like this
bob 3874 habit
scram 9984 sweater
flux 12 then

so each line ends up in a struct like this:
Code:
struct info {
     char *name;
     int *num;
     char *also;
} ray[3];
However, the number of such lines is indeterminate, so "ray[3]" won't work. This must be a common task. How can I create an array of structs that will grow when I add a new entry, so to speak? Or do I have to (COMPLETELY RIDICULOUS) have to just set ray[10000] or something, to make sure I have enough space?
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS
MK27 is online now   Reply With Quote
Old 08-27-2008, 10:39 AM   #2
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 8,740
Quote:
Originally Posted by mk27 View Post
COMPLETELY RIDICULOUS

Don't blame the language, blame yourself
Just wanted to point that out for comic relief.

Anyway, have you ever seen malloc and realloc before?
tabstop is offline   Reply With Quote
Old 08-27-2008, 10:39 AM   #3
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,368
Quote:
How can I create an array of structs that will grow when I add a new entry, so to speak?
Use malloc() and free() from <stdlib.h>, e.g.,
Code:
#include <stdlib.h>

struct info {
    char *name;
    int *num;
    char *also;
};

int main(void) {
    struct info *ray;
    ray = malloc(3 * sizeof(*ray));
    /* Use ray[0], ray[1] and ray[2] here. */
    free(ray);
    return 0;
}
Though in the above example we do not actually expand the array, but that can be done with realloc(), also declared in <stdlib.h>.

Quote:
Or do I have to (COMPLETELY RIDICULOUS) have to just set ray[10000] or something, to make sure I have enough space?
That is actually an option: if you have a small enough upper limit of the number of elements, then you might decide to create an array of that size and just use as much of it as is needed.

EDIT:
Gah, it looks like the tutorials and FAQs here only touch on dynamic memory allocation with respect to C++. Anyway, search the Web and you will find more info. Also, you might note that my example does not include checking the return value of malloc() for NULL, but checking whether the allocation failed is good practice.
__________________
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

Last edited by laserlight; 08-27-2008 at 10:43 AM.
laserlight is online now   Reply With Quote
Old 08-27-2008, 10:40 AM   #4
and the hat of sweating
 
Join Date: Aug 2007
Location: Toronto, ON
Posts: 3,120
Switch to C++ and use a vector which is like an array and it can grow.
cpjust is offline   Reply With Quote
Old 08-27-2008, 10:43 AM   #5
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,946
malloc and realloc will do! I just didn't see how to use them with an array...thanks.

phew! I thot i was crazy.
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS

Last edited by MK27; 08-27-2008 at 10:46 AM. Reason: phew! I thot I was crazy.
MK27 is online now   Reply With Quote
Old 08-27-2008, 03:43 PM   #6
Registered User
 
Join Date: Aug 2008
Posts: 67
Quote:
Originally Posted by MK27 View Post
malloc and realloc will do! I just didn't see how to use them with an array...thanks.

phew! I thot i was crazy.
This may be of use to you: http://www.macs.hw.ac.uk/~rjp/Course.../linklist.html
http://cslibrary.stanford.edu/103/LinkedListBasics.pdf
kpreston is offline   Reply With Quote
Old 08-27-2008, 07:51 PM   #7
Banned
 
master5001's Avatar
 
Join Date: Aug 2001
Location: Visalia, CA, USA
Posts: 3,699
The STL vector idea isn't a horrible one, but I wouldn't tell someone who says "How much is gas, my Tahoe is a gas guzzler" "Oh the Toyota dealership is down the road to sell you a more fuel efficient vehicle."

So in the spirit of answering the question without intense sarcasm: The linked list thing may be a better solution since it can be cheaper than resizing. On the other hand, for what you are doing, since you can just resize by a large factor, you may find it no more expensive to just use malloc() and realloc().
master5001 is offline   Reply With Quote
Old 08-27-2008, 08:33 PM   #8
and the Hat of Ass
 
Join Date: Dec 2007
Posts: 731
I gave a link to a nice reference to dynamic memory allocation in the other thread.
rags_to_riches is offline   Reply With Quote
Old 08-27-2008, 08:39 PM   #9
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,946
hmmm...what's "fuel efficiency" about here: the awkwardness of having to use realloc, or the expense of learning C++ when I just rolled C off the lot last month...

I gotta thank kpreston, actually, as I have saved his refs for later. But right now a simple malloc suffices (the array doesn't really need to grow, but its initial size is a variable, and the struct must be global).

It didn't occur to me to use sizeof that way; up to now the only (error checked) malloc calls I've made have been simple character arrays, and multipying by 1 is easy.

I think the reason I started to write this was that I thot master5001 might have some deeper performance issues in mind. Now I'm not so sure.
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS
MK27 is online now   Reply With Quote
Old 08-27-2008, 10:26 PM   #10
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,368
Quote:
I gotta thank kpreston, actually, as I have saved his refs for later.
Be warned that the first article may appear much simpler than the second, but the example given fails to free the memory allocated. The second article is much more comprehensive, but perhaps a little more intimidating.

Quote:
I think the reason I started to write this was that I thot master5001 might have some deeper performance issues in mind. Now I'm not so sure.
Do you need to quickly add elements in the middle? If so, consider a linked list. Do you need to quickly access elements anywhere? If so, consider an array-like structure like a vector. Expanding a linked list from the middle (assuming that you already have a pointer to the insertion point) takes constant time, but expanding a dynamic array from the middle takes linear time (but expanding it from the end also takes constant time, in the long run, if you double the allocation whenever you need to expand). On the other hand, accessing the middle of a linked list takes linear time if you start from the head, while arrays have random access.
__________________
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 online now   Reply With Quote
Old 08-27-2008, 11:47 PM   #11
and the Hat of Ass
 
Join Date: Dec 2007
Posts: 731
Realloc example:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LINE_BUF_SZ 1024
static const unsigned int RAY_CHUNK_SIZE = 10;

typedef struct _info
{
   char *name;
   int num;
   char *also;
} info;

void print_data(const info **data, const unsigned int count)
{
   unsigned int i = 0;
   for ( ; i < count; ++i)
   {
      printf("Entry %u: %s %d %s\n", i,
            data[i]->name, data[i]->num, data[i]->also);
   }
}

void free_data(info **data, const unsigned int count)
{
   unsigned int i = 0;
   for ( ; i < count; ++i)
   {
      free(data[i]->name);
      free(data[i]->also);
      free(data[i]);
   }
}

int main()
{
   char line[LINE_BUF_SZ];
   char temp_name_buf[LINE_BUF_SZ], temp_also_buf[LINE_BUF_SZ];
   FILE *fp = fopen("dyndata.txt", "r");
   if (!fp)
      return -1;

   unsigned int ray_count = RAY_CHUNK_SIZE;
   info **ray = calloc(ray_count, sizeof(*ray));
   if (!ray)
      return -1;

   unsigned int line_count = 0;
   while(NULL != (fgets(line, sizeof(line), fp)))
   {
      if (line_count + 1 == ray_count)
      {
         // Need realloc                                                         
         info ** temp = realloc(ray, (ray_count += RAY_CHUNK_SIZE) * sizeof(*ray));
         if (!temp)
         {
            free_data(ray, line_count);
            free(ray);
            return -1;
         }
         ray = temp;
      }

      ray[line_count] = calloc(1, sizeof(info));
      if (!ray[line_count])
         return -1;

      if (3 != sscanf(line,
                      "%s %d %s",
                      temp_name_buf,
                      &ray[line_count]->num,
                      temp_also_buf))
      {
         return -1;
      }

      ray[line_count]->name = strdup(temp_name_buf);
      ray[line_count]->also = strdup(temp_also_buf);
      ++line_count;
   }

   print_data((const info **)ray, line_count);

   free_data(ray, line_count);
   free(ray);

   fclose(fp);

   return 0;
} 

Last edited by rags_to_riches; 08-27-2008 at 11:51 PM. Reason: Consistency
rags_to_riches is offline   Reply With Quote
Reply

Tags
absurdity, arrays

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Dynamic Array Resizing dld333 C++ Programming 13 11-04-2005 12:13 AM
need help with dynamic array syntax soldyne C Programming 3 10-11-2005 01:59 PM
Class Template Trouble pliang C++ Programming 4 04-21-2005 04:15 AM
2D dynamic array problem scsullivan C Programming 3 12-30-2002 10:02 PM
Dynamic array allocation and reallocation purple C Programming 13 08-01-2002 11:48 AM


All times are GMT -6. The time now is 10:25 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22