2

It's weird because I have done it before but it just is not working. I have a structure xmp_frame like this.

typedef struct {
    short int attr_dtype;
    short int attr_code;
    short int attr_len;
    const char *attr;
}xmp_frame;

Now I create an array of xmp_frame and use them like:

xmp_frame frame_array[]={
    {1,2,strlen("Hello there"),"Hello there"},
    {1,3,strlen("This is not working"),"This is not working"},
    {0,3,strlen("But why??"),"But why??"}
};

Now I have a routine which basically writes the frame_array in to file:

short int write_frames(xmp_frame frame_array[],FILE *outfp){

}

Before I write the frame_array I need to get the no. of elements in frame_array[] for doing some processing. So this is how we do it (generally):

short int write_frames(xmp_frame frame_array[],FILE *outfp) {
    short intnum_frames=sizeof(frame_array) / sizeof(frame_array[0]);
   /*But i get the value of num_frames as 0. I will print the outout of some debugging.*/ 

    fprintf(stderr,"\n Size of frame_array : %lu",sizeof(frame_array));  //prints 8
        fprintf(stderr,"\n Size of frame_array[0] : %lu",sizeof(frame_array[0])); //prints 16
       fprintf(stderr,"\n So num. of frames to write  : %d",  (sizeof(frame_array))/(sizeof(frame_array[0]))); //prints 0 
}

Of course if frame_array is 8 bytes and frame_array[0] is 16 bytes then num_frames is going to be 0.

But the question is how can size of an array be smaller than one of its elements? I heard about byte padding.

I don't have much of an idea if it is causing the problem. Here is one of the links I referred to: Result of 'sizeof' on array of structs in C?

Although I have found a few workarounds to determine the size of an array of structs.

  1. Get the no. of elements from the caller and

  2. another is compulsorily get the last struct element as {0,0,0,NULL} and then in write() check for it's presence and stop scanning frame_array any further.

But both depend on the caller, something which you can't trust. So where is the real problem. And how could I determine the value of num_frames?

Community
  • 1
  • 1
tnx123456
  • 125
  • 2
  • 8

4 Answers4

4

Arrays are passed to functions as pointers, so the 8 bytes you are seeing is really the size of a pointer (assuming you're on 64-bit) and not the size of the original array. There is no way to retrieve the actual size of the pointed-to array, so you'll have to pass it separately to the function.

casablanca
  • 69,683
  • 7
  • 133
  • 150
1

There is no way to know a size of an array once it was passed as a parameter to a function. You need to pass the number of the elements in the array.

short int write_frames(xmp_frame frame_array[], int num_frames,FILE *outfp)
{
    for(int i=0; i < num_frames; i++)
        // write frame_array[i]
}
Krzysztof Kozielczyk
  • 5,887
  • 37
  • 28
0

You can do it with this function :

size_t _msize(void *memblock);

and call it when you want with your structure array pointer.

dbush
  • 205,898
  • 23
  • 218
  • 273
AvE
  • 1
0

Size of an array and hence the number of elements in an array are fixed at compile time. If we do not specify a value of a element of array during initialization, it will be set to 0 (or null in case of char) by default.

So here is how I get the number of initialized elements of a array of structure :

int main ()
{
  struct stations  //Define a structure
  {
    char *ssid;
    char *pw;
    int count;
  };

  struct stations sta[10]; //Create array of above sturcture
  int n;
  n = sizeof (sta) / sizeof (sta[0]); //Get total number of elements in array
  printf ("Number of total elements in array, n=%d\n", n);
// initialize a few elements of array
  sta[0].ssid = "ssid0";
  sta[0].pw = "pw0";
  sta[0].count = 1;

  sta[1].ssid = "ssid1";
  sta[1].pw = "pw1";
  sta[1].count = 2;

  sta[2].ssid = "ssid2";
  sta[2].pw = "pw2";
  sta[2].count = 3;

  // Iterate through all 10 elements of array to find members with value equal to zero or null

  for (int i = 0; i < 10; i++)
    {
      if (sta[i].ssid != 0)
    {
      printf ("%s\n", sta[i].ssid);
      printf ("%s\n", sta[i].pw);
      printf ("%d\n\n", sta[i].count);
    }
      else
    {
      printf ("sta[i].ssid =%s\n", sta[i].ssid);
      printf ("sta[i].count =%d\n", sta[i].count);

      // each time you encounter element with value=0(or NULL), reduce n by one .

      n = n - 1;

    }

    }
  printf ("Number of initialized (non zero) elements in array, n=%d\n", n);
}

This is the output I get:

Number of total elements in array, n=10
ssid0
pw0
1

ssid1
pw1
2

ssid2
pw2
3

sta[i].ssid =(null)
sta[i].count =0
sta[i].ssid =(null)
sta[i].count =0
sta[i].ssid =(null)
sta[i].count =0
sta[i].ssid =(null)
sta[i].count =0
sta[i].ssid =(null)
sta[i].count =0
sta[i].ssid =(null)
sta[i].count =0
sta[i].ssid =(null)
sta[i].count =0
Number of initialized (non zero) elements in array, n=3
Zeni
  • 947
  • 1
  • 12
  • 24