Solved

Dynamic arrays

Posted on 2004-10-26
371 Views
Last Modified: 2010-04-15
Hi,
   I was wondering whether it was possible to use dynamic arrays in C or if not something which does the job of?

  Here is my scenario. I am reading values (of which there are multiples) from an Oracle table. Each time I read a record i want to write it to another table, however I only want to do this if I haven't already written a record for that specific value. For this reason I wanted to write the value to an array and then check this array each time I read in a new record. My problem is that I have no idea how many unique values there are so I don't want to size the array at the start?

p.s. I cannot restrict my result set in oracle as there are other tables that I need to create for every record.

Any ideas would be much appreciated.

Dust.
0
Question by:dustybryn
    8 Comments
     
    LVL 5

    Expert Comment

    by:van_dy
    Hi Dust,
          Well yes it is possible to allocate memory dynamically in C. You
    do that by using the stdlib function malloc(). take a look at the manpage for
    it.  However your idea of storing the already written values in a dynamically allocated array
    will make the search for a record in your array very slow. i would suggest
    you to build an in memory binary tree of already stored values.(lookup in a
    tree is relatively faster.
    0
     

    Author Comment

    by:dustybryn
    Thanks for this, can you give me some example code please.
    0
     
    LVL 55

    Assisted Solution

    by:Jaime Olivares
    Hi Dust,
    Although van_dy suggestion is correct, I think binary trees are a bit complex to begin with.
    If your data is not to big, I suggest you to store it in another dynamic collection: single linked list

    You can learn about them at:
    http://cslibrary.stanford.edu/103
    http://cslibrary.stanford.edu/105
    0
     
    LVL 5

    Assisted Solution

    by:van_dy
    ok here is how it goes:

    typedef struct node{
               char *entry;
               struct node *lnode;
                struct node * rnode;
    } node;
     

    int main()
    {
             node *root = NULL;          // root of our tree
            char entry[256];                   // the record is read in this buffer
             while(read_from_O_table(entry, tablename1)){      //this function reads nextentry from the table named
                                                                                     // tablename1; you    
                                                                                //  should have implemented it since it depends on the format of the
                                                                                // table and which entry in a record uwant.
                           if(present_in_tree(entry, root))       //if the currently read entry is in tree, we dont need to write
                                                                                 //it to the table
                                    continue;
                           add_to_tree(entry, root);                //add the entry to tree
                           write_entry_to_O_table(entry, tablename2);   // this function will write the entry to the table
                                                                                                   // whose name is tablename2.
              }
    }

    Now the critical functions you need to implement are present_in_tree() and add_to_tree(). the actual implementation
    requires some non trivial coding. I would suggest you to take a look here
    http://www.cs.bu.edu/teaching/c/tree/bst/#algorithm

    hope this helps,
    van_dy
    0
     
    LVL 7

    Expert Comment

    by:ravs120499
    Hi,

    Yes, I would also recommend using linked lists. But if you must use dynamic arrays, here is how it can be done...

    typedef struct
    {
    ...
    } my_record;

    static my_record *ptr_records = NULL;
    static long num_records = 0;

    /* Takes a new record and tries to add it to the array.
     * Returns the index to the new record in the array, or -1 if unsuccessful.
     */
    long add_record(my_record *rec)
    {
        my_record *temp_ptr_records;

       /* Calculate the new size required for realloc */
        size_t newsize = sizeof(my_record) * (num_records+1);

        /* Realloc and check for failure */
        my_record *temp_ptr_records = (my_record *)realloc(ptr_records, newsize);
        if(temp_ptr_records == NULL)
            return -1;

        /* Realloc succeeded */
        ptr_records = temp_ptr_records;
        return num_records++;
    }

    long search_record(my_record *ptr_rec)
    {
    /* You get the picture */
    ...
    }

    void main(int argc, char **argv)
    {
       ....
       /* Unique record found */
       index = add_record
    }

    A variation on this is to make ptr_records a double pointer - like so: my_record **ptr_records. In this case, you will have to realloc an extra pointer to my_record * every time AND also malloc a my_record every time, and set the newly allocated pointer to point to the newly allocated my_record struct (sorry for the complicated sentence). The advantage is that the realloc will be faster since it has to copy less amount of data to the newly allocated memory (N pointers instead of N my_record structs).

    Regards
    0
     
    LVL 12

    Expert Comment

    by:stefan73
    Hi dustybryn,
    What you're trying to achieve is not uncommon. I suggest you have a closer look at PL/SQL's functionality instead of taking the C detour.
    You could use a temporary table, for example.

    In case you want to work with a C solution, check C's hsearch(), hcreate(), hdestroy() functions. From the man page:

         #include <search.h>
         ENTRY *hsearch(ENTRY item, ACTION action);
         int hcreate(size_t mekments);
         void hdestroy(void);


    Cheers!

    Stefan
    0
     
    LVL 12

    Expert Comment

    by:stefan73
    Another alternative is to set a unique index on your target table's column. You could catch the "Unique constraint violated" error and ignore it.
    0
     
    LVL 45

    Accepted Solution

    by:
    Hi dustybryn,

    Dynamic arrays are a fundamental part of C.  The versatility of the language syntax (See also, 'overlap') allows you to dynamically create one-dimensional arrays anywhere that you find convenient.  Multiply dimensioned arrays (matrices) are another issue and require quite a bit more work.

    I'm going to disagree with the other experts here and suggest that you do NOT want to used linked lists.  C will allow you to build dynamic arrays and they will suffice quite well for your use.

    Adding and testing integers is almost trival.  (It would be an ideal C++ class, but still very manageable in C.)

    Here's some sample code.  You only need the first two fields to manage a dynamic integer table.  I've added the last two for efficiency.

    int *IntTable = NULL;              /*  Integer table  */
    int IntTableCount = 0;             /*  Number of integers stored in table  */
    int IntTableReserved = 0;        /*  Number of integers reserved via last malloc() or realloc()  */
    int IntTableIncrement = 100;   /*  Number of integers to add to each table each call to realloc()  */

    /*
      SaveIntegerInTable -- Save an integer value in the integer table

      returns 0 if the value was not in the table when the function was called.
      returns 1 if the value was in the table when the function was called.

      Upon exit, the value will have been saved in the table
    */

    int SaveIntegerInTable (int Value)
    {
      int idx;

    /*  Search to see if the value already exists in the table  */

      for (idx = 0; idx < IntTableCount; idx++)
        if (IntTable[idx] == Value)
          return 1;

    /*  It wasn't found, so add it  */

      if (IntTableCount == IntTableReserved)      /*  There's no room in the table for another entry  */
      {
        IntTableReserved += IntTableIncrement;  /*  Set the new table size  */
        IntTable = (int *)realloc (IntTable, IntTableReserved * sizeof (int));
      }
      IntTable[IntTableCount++] = Value;           /*  Store the target value  */
      return (0);                                                /*  Return a *not found* condition after storing the value  */
    }

    Kent
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone. Privacy Policy Terms of Use

    Featured Post

    Threat Intelligence Starter Resources

    Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

    Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
    This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
    The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
    The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.

    877 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    20 Experts available now in Live!

    Get 1:1 Help Now