• C

Dynamic arrays

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.
dustybrynAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

van_dyCommented:
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
dustybrynAuthor Commented:
Thanks for this, can you give me some example code please.
0
Jaime OlivaresSoftware ArchitectCommented:
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
Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

van_dyCommented:
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
ravs120499Commented:
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
stefan73Commented:
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
stefan73Commented:
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
Kent OlsenData Warehouse Architect / DBACommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.