Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Dynamic arrays

Posted on 2004-10-26
8
Medium Priority
?
391 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
Comment
Question by:dustybryn
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
8 Comments
 
LVL 5

Expert Comment

by:van_dy
ID: 12411397
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
ID: 12411615
Thanks for this, can you give me some example code please.
0
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 100 total points
ID: 12411824
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
Industry Leaders: 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!

 
LVL 5

Assisted Solution

by:van_dy
van_dy earned 100 total points
ID: 12412013
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
ID: 12412131
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
ID: 12412519
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
ID: 12412555
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 46

Accepted Solution

by:
Kent Olsen earned 200 total points
ID: 12413888
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

Featured Post

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.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
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 and use switch statements in the C programming language.

610 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