简体   繁体   中英

C array: setting element at offset

I have a 2D array declared as

static bool array[ROW][COL];

Instead of using the indices, for a particular function I want to use a byte offset to set some of the elements, since the bools in this array are pretty much guaranteed to be 1 byte each.

loff_t *offset = 0;

So I try the following line.

array + *offset = false;

However, it compiles with the warning "lvalue required as left operand of assignment". What's wrong with this implementation, and how can I set the element of an array based on byte offset?

Instead of specifying byte offset directly by messing around with pointers while trying to avoid undefined behavior, you could just manually compute the indices for a specific offset:

array[offset / COL][offset % COL] = ...

Above will work only if sizeof (bool) == sizeof (char) .

If your program already makes such assumption, you should add following:

static_assert(sizeof (bool) == sizeof (char), "sizeof bool != sizeof char");

If not, you should use different (pointer based) approach.

You can use an offset into the 2D array as if it were a 1D array, but it is not strictly correct as you are indexing beyond the subarray boundary:

*(array[0] + *offset) = false;         // not strictly correct

For this syntax, offset must contain a number of bool types, computed like this:

*offset = &array[row][col] - array[0];

or equivalently: *offset = &array[row][col] - &array[0][0];

An alternative is to alias with a character type, but bool might be larger than char , so this would be incorrect too:

*((char*)array + *offset) = false;  // potentially incorrect

To handle the case of bool larger than char , we may use:

*(bool *)((char*)array + *offset) = false;  // quite ugly

And offset should be computed this way:

*offset = (char*)&array[row][col] - (char*)array;

Setting a bool value stored in the array array at byte offset *offset will look as follows

*(bool *) ((char *) array + *offset) = true;

Of course, you will have to assume all risks that follow from this kind of access, since technques like this can easily run afoul of strict-aliasing rules. A safer alternative might be

bool new_value = true;
memcpy((char *) array + *offset, &new_value, sizeof new_value);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM