• C

Array size

Hi,
I have an array like long *x  for which memory is allocated thru malloc. Depending on requirement the size will be increased using realloc. At some later stage I need to check if a particular number is present in the array. How can I get the number of elements present in the array at any given point of time.
p_srinivAsked:
Who is Participating?
 
Kent OlsenConnect With a Mentor Data Warehouse Architect / DBACommented:
Hi Sunny,

I don't like the idea of putting the "array size" in the first element.  With C's inherent "arrays start at index 0" philosophy using index 0 as the size alters the characteristics of the array.  And it only works for int type variables.

for (i=0; i < array_size; i++);  /*  universally accepted way to traverse an array  */

for (i=1; i <= array_size; i++); /*  traverse a relative 1 array  */

The problem will come later when you try and maintain the code.  You'll see the second for(;;) statement and be forced to investigate it as if it were an error.


I usually use a small structure to maintain dynamic arrays.  That way I can have as many as the program needs and keep the control data for each isolated from the other arrays and use a common set of code to maintain them.

typedef struct
{
  int  ReservedCount;  /*  Number of integers in the array  */
  int  InUse;          /*  Highest index in use  */
  int  *Data;          /*  Integer array  */
} IntArray_t;


IntArray_t  IntArray = { 0,0,0 };





Good Luck,
Kent
0
 
Sjef BosmanGroupware ConsultantCommented:
You can't. You have to store that in a separate variable and update it when you malloc/realloc.
0
 
sunnycoderCommented:
Hi p_sriniv,

There is no way to get the number of elements in the array unless you explicitly store it somewhere ... How about using first location on the array as number of elements ?

Sunnycoder
0
Protect Your Employees from Wi-Fi Threats

As Wi-Fi growth and popularity continues to climb, not everyone understands the risks that come with connecting to public Wi-Fi or even offering Wi-Fi to employees, visitors and guests. Download the resource kit to make sure your safe wherever business takes you!

 
stefan73Commented:
Hi p_sriniv,
Probably you already have the size somewhere already, since you do realloc.

Here is a small code snippet which does realloc with a slop factor of 2, used to store input lines of arbitrary size:

static char*  tokbuf=NULL;
static size_t maxtokbuf=0;
static size_t curtokbuf=0;


if(!tokbuf){
      tokbuf    = (char*)malloc(100);
      maxtokbuf = 100;
}


if(curtokbuf == maxtokbuf){
      maxtokbuf *= 2;
      tokbuf=(char*)realloc(tokbuf,maxtokbuf);
}
tokbuf[curtokbuf++]=tok;

You could easily wrap this in a declaration/use macro pair.

Cheers,
Stefan
0
 
ankuratvbCommented:
You could use wrappers for malloc/realloc and update the value of a size variable to store the size.

Sunny's idea of storing the size in the first element is a good idea.
0
 
stefan73Commented:
ankuratvb,
> storing the size in the first element
Pascal strings? :-)

Stefan
0
 
ankuratvbCommented:
Stefan,
Never Studied Pascal. :~))

My first language was good old BASIC.
0
 
ankuratvbCommented:
Here is an example of the wrappers:

#include<alloc.h>
int size=0;
void *mymalloc(size_t s);
void *realloc(void *block, size_t size);

int main()
{
 int *x;
 x=(int *)mymalloc(100);
 printf("%d",size);
 return 0;
}
void *mymalloc(size_t s)
{
 size=s;
 return malloc(size);
}
void *realloc(void *block, size_t s)
{
 size=s;
 return realloc(block,size);
}

0
 
ankuratvbCommented:
>void *realloc(void *block, size_t size);

should be:

void *myrealloc(void *block, size_t size);
in both declaration and definition.
0
 
grg99Commented:
You can keep the array size in the [-1]st array index, with a little footwork:

int * myalloc( int Len )
{
   p = malloc( ++Len * sizeof(int) );
   *p = Len;
  return( p++ );
}

void myfree( int * p )
{
    free( --p );
}
0
 
Sjef BosmanGroupware ConsultantCommented:
The return from myalloc isn't correct, should be

    return ++p;

Beware: the array cannot be longer than 32767 bytes...
0
 
ankuratvbCommented:
Just out of curiosity,

What would be the result of return p++;
coz by the time the next sequence point occurs,p would be out of scope.

Or does ( ) define a sequence point?
0
 
Sjef BosmanGroupware ConsultantCommented:
It is even better to
    return p+1
0
 
sunnycoderCommented:
Hi Kent,

I too personally use the same struct as you do, though I do not use such descriptive names (mine are i,j and p ... I am still learning :) ) ... However, here question said array of longs ... So it gets a bit more compact (or atleast I feel so) ... But that the struct approach is more elegant still stands

>using index 0 as the size alters the characteristics of the array
May be you have programmed too long with C :o) ... Its all numbers!! ... one or one more does not matter unless you are stuck with one as a matter of habit ;o)

sunny
0
 
Kent OlsenData Warehouse Architect / DBACommented:
Hi Sunny,

Actually, I use the structure here:

#include "storage.h"

typedef      struct
{
      UInt32   entries;     /*  Number of entries in use  */
      UInt32   reserved;    /*  Number of entries in the reserved memory  */
      UInt16   increment;   /*  Number of items to add each extent  */
      UInt16   entry_size;
      boolean  entries_are_pointers;
      char      *buffer;
} TABLE_t;

storage.h contains the machine dependent types so that the structure is a consistent size.  I have an entire library that manages the data by managing this structure.  A long time ago I got tired of debugging pointer errors so I built the library.  Almost every C program that I've written in the last 10+ years uses it for something.

>>using index 0 as the size alters the characteristics of the array
>May be you have programmed too long with C :o) ... Its all numbers!! ... one or one more does not matter unless you are stuck with one as a matter of habit ;o)

Reread my entire comment.  Using index 0 as anything other than the first data element alters the way that you index the array. Debugging aquires its own set of complications.


Kent
0
 
sunnycoderCommented:
>Debugging aquires its own set of complications.
Because we have been trained to think that way ... "0 is the first location for data"

My struct is a bit different ... I uniformly use void *s and keep track of capacity and used locations only ... dirty but convinient
0
 
Kent OlsenData Warehouse Architect / DBACommented:

I should use void* for buffer, but pointer math requires a length of the object.  char* simply makes life easier.  I recast before returning data addresses so the returned address is of the expected type.

Kent
0
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.

All Courses

From novice to tech pro — start learning today.