Reputation: 119
Assume i have define structure which has one array. I have initialize the array in main program. But now how can i find the number of element initialized in the array. I have created arrays of struct object too.
#include <stdio.h>
#define noOfArray 10
struct Arrays
{
int data[100];
int size;
int discardArray; //1 for true and 0 for false
};
void main( )
{
int size=0,i,j;
struct Arrays arrayObject[10]={
{{1,2,3,4}},
{{1,3,5,6,3,4}},
{{1,6,7,8,9,10,11,43,4}}
};
size = sizeof arrayObject[0].data / sizeof arrayObject[0].data[0];
}
This size gives me 100 but i need total number of element present in arrayObject[0].data.
Event tried with
int arr[] = {1,2,3,4};
struct Arrays arrayObject[10] = {
{arr,sizeof arr/sizeof arr[0]},
{{1,3,5,6,3,4}},
{{1,6,7,8,9,10,11,43,4}}
};
But this doesn't compile: Near to sizeof start
it is saying invalid initialization.
What I'm really looking for is any way to store n
arrays, where the first array can be compared to other arrays. The element preset in the arrays with be of varying size.
Upvotes: 1
Views: 435
Reputation: 34849
One solution is to put a sentinel value at the end of the array. For example, if negative values are not normally allowed in the array, then you could use the value -1
to mark the end of the array.
struct Arrays arrayObject[10]={
{{1,2,3,4,-1}},
{{1,3,5,6,3,4,-1}},
{{1,6,7,8,9,10,11,43,4,-1}}
};
This allows you to use a simple for
loop to count the number of valid entries in the array.
Upvotes: 1
Reputation: 366104
The flaw in what you're trying to do is the way you're trying to distinguish between initialized vs. uninitialized elements.
int a[100] = { 1, 2 };
Does initialize all 100 elements. The elements not mentioned in the initializer list are initialized to zero. You can't use sizeof(a)/sizeof(a[0])
to count initialized elements.
You could do something like
#define INIT_LIST { 1, 2, 111} // 257
#define ASIZE 100
int big_array[ASIZE] = INIT_LIST;
// this works with gcc -O1 / -Og, but dummy is there in the object file at -O0
static const char dummy[] = INIT_LIST;
int initialized_count = sizeof(dummy); // sizeof(char) is guaranteed to be 1, so no divisor is needed.
// Or even better, no dummy array in the object file even with -O0:
int initialized_count2 = sizeof((int[])INIT_LIST)/sizeof(int);
// This also avoids compiler warnings when constants in the initializer list don't fit in a char.
// in macro form: Be careful with very large initializers; this could compile slowly if you used it all over the place.
#define COUNT_INITLIST (x) (sizeof((long[])x)/sizeof(long))
// Even with optimization on, this will also compile away to just returning a constant
int initialized_in_big_array() {
// without optimization: dummy2 is there in the object file
// but still not copied to the stack, because of const
const char dummy2[] = INIT_LIST;
return sizeof(dummy2);
}
It turns out even at low optimization levels like -Og
, compilers avoid emitting unused arrays entirely. So the inline-function isn't needed. Jens Gustedt's suggestion of casting the initializer list, so there is never an array, is the best.
Upvotes: 2
Reputation: 1164
Your compile time error is that you're trying to use arr
as a value to initialize arrayObject to. However, C only allows values that are known at compile time to be used as initializers. arr
is an address on the stack that won't be known until execution time, therefore it can't be used as an initializer.
You should be able to initialize to sizeof arr/sizeof arr[0]
, which will be the count of elements in the array, but you can't initialize to arr, sizeof arr/sizeof arr[0]
.
Upvotes: 2