Is it possible to find the address of the end of an array with a reference to the n+1th element?

0

I need to know when the pointer went through the whole array -> is on the first position behind it. Examplecode in c:

unsigned int ar[10];
char *pointer = (char*) ar;
while(pointer != (char*) &ar[10]){
*pointer++ = 0xff
}

Would this example work to set every element of the array to 0xffffffff?

arrays
c
pointers
array-pointer
asked on Stack Overflow Sep 4, 2020 by Nemora • edited Sep 5, 2020 by Nemora

2 Answers

1

The principle is right but you forgot to initialize the pointer and are incrementing it in the wrong place. Rather use

unsigned int ar[10];
unsigned char *pointer = (unsigned char *)ar;
unsigned char *end = (unsigned char *)&ar[10];
while (pointer != end) { 
    *pointer++ = 0xff;
}

if you increment the pointer in the comparison, then you will not set the first byte and will write one byte past the limit.

But never reinvent the wheel. There is a function in <string.h> for this:

unsigned int ar[10];
memset(ar, 0xff, 10 * sizeof (int));

// or if a static array,
memset(ar, 0xff, sizeof ar);

On the other hand, if you really want to set the unsigned ints to UINT_MAX, then you could be explicit:

for (size_t i = 0; i < 10; i++) {
    ar[i] = UINT_MAX; // or you could use `-1` as well, as it is guaranteed to result in `UINT_MAX` after conversion.
}
answered on Stack Overflow Sep 4, 2020 by Antti Haapala • edited Sep 4, 2020 by Antti Haapala
0

When working with raw binary, I'd recommend to use an unsigned character type such as uint8_t instead of char, since the latter has implementation-defined signedness.

Then there are two special rules in C you can utilize:

C11 6.3.2.3/7

When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.

This allows us to inspect or modify the raw binary contents of any type in C by using a character pointer. So you can indeed set every byte of the integer array to 0xFF using a character pointer.

The other special rule is hidden inside how the additive operators work, since the [] operator is just syntactic sugar around + and dereference. C11 6.5.6/8, emphasis mine:

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

This allows us to check the address 1 int beyond the end of the array.

However converting between a character type pointer and an int pointer creates misaligned pointers and that (at least in theory) invokes undefined behavior and possibly instruction traps. So you can't just cast the character pointer to an integer pointer and compare.

So the completely correct way would be to increase the character pointer by sizeof(int) then set 4 bytes each lap in the loop.

Meaning that the following is an well-defined (but cumbersome & hard-to-read) way of setting all bytes in the array:

#include <stdio.h>
#include <stdint.h>

int main (void)
{
  unsigned int arr[10];
  
  for(uint8_t* i = (uint8_t*)arr; (unsigned int*)i != &arr[10]; i+=sizeof(unsigned int))
  {
    i[0] = 0xFF;
    i[1] = 0xFF;
    i[2] = 0xFF;
    i[3] = 0xFF;
  }
  
  for(size_t i=0; i<10; i++)
  {
    printf("%X\n", arr[i]);
  }

  return 0;
}
answered on Stack Overflow Sep 4, 2020 by Lundin • edited Sep 4, 2020 by Lundin

User contributions licensed under CC BY-SA 3.0