pop850
pop850

Reputation: 3157

How to check if "set" in c

If I allocate a C array like this:

int array[ 5 ];

Then, set only one object:

array[ 0 ] = 7;

How can I check whether all the other keys ( array[1], array[2], …) are storing a value? (In this case, of course, they aren't.)

Is there a function like PHP's isset()?

if ( isset(array[ 1 ]) ) ...

Upvotes: 6

Views: 5857

Answers (6)

kennytm
kennytm

Reputation: 523244

There isn't things like this in C. A static array's content is always "set". You could, however, fill in some special value to pretend it is uninitialized, e.g.

// make sure this value isn't really used.
#define UNINITIALIZED 0xcdcdcdcd

int array[5] = {UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED};

array[0] = 7;

if (array[1] != UNINITIALIZED) {
   ...

Upvotes: 7

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215221

An approach I like is to make 2 arrays, one a bit-array flagging which indices of the array are set, and the other containing the actual values. Even in cases where you don't need to know whether an item in the array is "set" or not, it can be a useful optimization. Zeroing a 1-bit-per-element bit array is a lot faster than initializing an 8-byte-per-element array of size_t, especially if the array will remain sparse (mostly unfilled) for its entire lifetime.

One practical example where I used this trick is in a substring search function, using a Boyer-Moore-style bad-character skip table. The table requires 256 entries of type size_t, but only the ones corresponding to characters which actually appear in the needle string need to be filled. A 1kb (or 2kb on 64-bit) memset would dominate cpu usage in the case of very short searches, leading other implementations to throw around heuristics for whether or not to use the table. But instead, I let the skip table go uninitialized, and used a 256-bit bit array (only 32 bytes to feed to memset) to flag which entries are in use.

Upvotes: 1

I don't know php, but one of two things is going on here

  • the php array is actually a hash-map (awk does that)
  • the php array is being filled with nullable types

in either case there is a meaningful concept of "not set" for the values of the array. On the other hand a c array of built in type has some value in every cell at all times. If the array is uninitialized and is automatic or was allocated on the heap those values may be random, but they exist.

To get the php behavior:

  • Implement (or find a library wit) and use a hashmap instead on an array.
  • Make it an array of structures which include an isNull field.
  • Initialize the array to some sentinal value in all cells.

Upvotes: 2

Matthew Mitchell
Matthew Mitchell

Reputation: 5383

One solution perhaps is to use a separate array of flags. When you assign one of the elements, set the flag in the boolean array.

You can also use pointers. You can use null pointers to represent data which has not been assigned yet. I made an example below:

int * p_array[3] = {NULL,NULL,NULL};
        p_array[0] = malloc(sizeof(int));
        *p_array[0] = (int)0;
        p_array[2] = malloc(sizeof(int));
        *p_array[2] = (int)4;
        for (int x = 0; x < 3; x++) {
            if (p_array[x] != NULL) {
                printf("Element at %i is assigned and the value is %i\n",x,*p_array[x]);
            }else{
                printf("Element at %i is not assigned.\n",x);
            }
        }

You could make a function which allocates the memory and sets the data and another function which works like the isset function in PHP by testing for NULL for you.

I hope that helps you.

Edit: Make sure the memory is deallocated once you have finished. Another function could be used to deallocate certain elements or the entire array.

I've used NULL pointers before to signify data has not been created yet or needs to be recreated.

Upvotes: 1

Loki Astari
Loki Astari

Reputation: 264381

You can't

There values are all undefined (thus random).

You could explicitly zero out all values to start with so you at least have a good starting point. But using magic numbers to detect if an object has been initialized is considered bad practice (but initializing variables is considered good practice).

int array[ 5 ] = {};

But if you want to explicitly check if they have been explicitly set (without using magic numbers) since creation you need to store that information in another structure.

int array[ 5 ]   = {};  // Init all to 0
int isSet[ 5 ]   = {};  // Init all to 0 (false)

int getVal(int index)          {return array[index];}
int isSet(int index)           {return isSet[index];}
void setVal(int index,int val) {array[index] = val; isSet[index] = 1; }

Upvotes: 6

BiGYaN
BiGYaN

Reputation: 7159

In C, all the elements will have values (garbage) at the time of allocation. So you cannot really have a function like what you are asking for.

However, you can by default fill it up with some standard values like 0 or INT_MIN using memset() and then write an isset() code.

Upvotes: 2

Related Questions