3

I would like to test if myCurrentPtr points inside my array a.

_B represents the number of values in a.
So, a + _B shall point the latest value of the array.

#define _B ((uint8_t)5)
volatile uint8_t a[5] = {0, 1, 2, 3, 4}; //`a` is a pointer to the first array element

if (myCurrentPtr > (a + _B)) {
    printf("Out of bounds!");
}

Doesn't compile. Do you have any idea?

Whereas,

...
if (myCurrentPtr > (a + 5)) {
    printf("Out of bounds!");
}

compiles just fine.

Aren't the two exactly the same after preprocessing?

6
  • 5
    What error message? Commented Apr 6, 2020 at 21:31
  • Instead of (a + 5) use (a + sizeof(a)*sizeof (<type_of_a>)). Commented Apr 6, 2020 at 21:50
  • Do the C standards guarantee that comparisons applied to pointers are always implicitly and suitably casted? Commented Apr 6, 2020 at 21:57
  • 1
    "a + _B shall point the latest value of the array." --> No. a + _B points one pass the last. Commented Apr 6, 2020 at 22:06
  • 1
    Error message: « myfile.c:40:41: warning: (359) illegal conversion between pointer types pointer to volatile unsigned char -> pointer to unsigned char ». Anyway I don't really understand what the compiler expects, since my 2 examples should compile exactly the same. Commented Apr 7, 2020 at 17:52

1 Answer 1

2

How to test if pointer inside an array?

Code can use >=, >, <, <= between two object pointers p,q is they are in the same array (or just one passed the end of the array). Else code is undefined behavior. C does not have a portable way to test in/outside the array.

The below code is poor

if (myCurrentPtr == (a + _B)) {                            // Defined behavior
  printf("pointer just passed a[]\n"); 
} else if (myCurrentPtr >= a && myCurrentPtr < (a + _B)) { // Undefined behavior
  printf("pointer in array\n");        
} else {
  printf("pointer outside array\n");
}

Code could explicitly compare one at a time with ==, != with myCurrentPtr and each element of a[]. Likely this is unsatisfactorily slow, yet reliable.

// Dependable, well defined, but slow.
found = false;
for (int i=0; i<5; i++) {
  if (myCurrentPtr == &a[i]) {
    found = true;
    break;
  }
}

Other approaches rely on iffy code.

// Iffy code - depending on memory model, may work, may not.
uintptr_t mcp = (uintptr_t) myCurrentPtr;
uintptr_t ia =  (uintptr_t) a;
uintptr_t ia5 = (uintptr_t) &a[5];

if (mcp >= ia && mcp < ia5) {         // Not highly portable
  printf("pointer in array\n");        
} else {
  printf("pointer just passed a[]\n");
}

The best approach to "How to test if pointer inside an array?" is to re-form the problem. OP did not post why this test is needed. Good code typically can re-work the issue and not use this test.

Sign up to request clarification or add additional context in comments.

8 Comments

Great answer, thank you very much for all these illustrated examples! I think I'll re-form the problem as you advise. However I'd also like to know why my example with the #define doesn't compile and learn from this error
In your 1st example (defined behavior) if (myCurrentPtr == (a + _B)) raises the error, but if (myCurrentPtr == (a + 5)) doesn't
@TheJeje20 I suspect your 2 codes are not the same in other ways (perhaps difference on type of myCurrentPtr or a. Append 2 minimal reproducible example that demo the error and no error.
@TheJeje20 Try renaming _B to BBB and report success or failure. _B is a reserved identifier - you should not define it. "All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved ..."
Ok, there was no issue… My IDE is prehistoric! Looks like it needed me to manually refresh its knowledge databases before it launches compilation. So the two examples are valid and are the same as intended. Thank you for your help @chux
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.