8

All of the examples I've been able to find online about incrementing a pointer causing a segfault involved the dereference of the pointer - what if I just want to increment it (for example at the end of a for loop) and I don't care if it ends up in invalid memory because I won't use it again. For example, in this program I just need to step by 4 every iteration, but I never dereference these pointers again after the last iteration.

float* leftRowPointer, resultRowPointer;
// assume they were correctly initialized

for (unsigned int i = 0; i < 4; ++i, leftRowPointer += 4, resultRowPointer += 4) {
    // do some stuff
}

Do I need to do something like this instead?

for (unsigned int i = 0; i < 4; ++i) {
    // same stuff
    if (i != 3) {
        leftRowPointer += 4;
        resultRowPointer += 4;
    }
}

Is there a better way to accomplish what I'm trying to do?

When I've tried it myself nothing bad seems to happen, but that's hardly a guarantee that it will always work, and unfortunately I don't have access to Valgrind or similar at work.

We're using the C++11 standard, fwiw, and I couldn't find anything in there that directly applies to this, but I'll be the first to admit that I don't know the standard well enough to have a good idea of where to look for it.

Dan Oberlam
  • 2,435
  • 9
  • 36
  • 54
  • 1
    Look in Additive Operators (probably [expr.plus] or something like §5.5). – chris Jan 08 '16 at 15:24
  • What are the types of `leftRowPointer` and `resultRowPointer`? In general, incrementing pointers is safe. If, however, they're a custom type with overridden `operator +=`, then you'd need to look at the safety of the custom function. – inetknght Jan 08 '16 at 15:25
  • 1
    This might be useful to answer your question: http://stackoverflow.com/questions/2728299/why-is-comparing-against-end-iterator-legal – Aiden Deom Jan 08 '16 at 15:25
  • They're `float*` @inetknght. Thanks for the references chris and Aiden – Dan Oberlam Jan 08 '16 at 15:26
  • 1
    So since they're pointers to native types, simply incrementing the pointers should be safe (remember that you code is incrementing by four floats however, not four bytes). It only becomes potentially undefined behavior if you dereference them while they're pointing to an invalid address. – inetknght Jan 08 '16 at 15:28
  • 2
    I'm guessing that incrementing a pointer value is just that: incrementing a valid number in memory by the sizeof() its type, dont see how that could segfault. But not 100% sure though – Emile Vrijdags Jan 08 '16 at 15:28
  • On most systems, you'll get away with it. The standard is unlikely to guarantee that you will, though. Why not simply set the pointers inside the body of the loop (at the top)? Some mainframe architectures are interesting in the way they check pointers — and simply generating an invalid address could cause trouble, even without dereferencing it. – Jonathan Leffler Jan 08 '16 at 15:29
  • 3
    By the way, I'm very sure it's undefined behaviour to keep incrementing a pointer past the one-past-the-end, even without dereferencing it. Just to clear that up. That said, it's likely to work. – chris Jan 08 '16 at 15:30
  • Incrementing a variable that holds an integer (which happens to represent a location in memory) seems pretty well-defined. – Scott Hunter Jan 08 '16 at 15:33
  • I believe, there is some ambiguity in standard which allows someone eager to read it in such a way that simply making a pointer invalid would trigger undefined behaviour (something along the line of non-defined term 'use'). However, I am no language lawer and can't argue this case. – SergeyA Jan 08 '16 at 15:34
  • Do not understand - how could it segfault? A pointer is a number, memory address. If we do not try accessing memory contents (dereferencing) - why should it segfault? – John_West Jan 08 '16 at 15:38
  • @John_West although that's true on common modern architectures, there have been machines where addresses are stored in special address registers and those registers have hardware support that only allows them to point to "real" memory addresses. (Sorry I don't have any references handy to back this up though) – jcoder Jan 08 '16 at 16:18

2 Answers2

8

Section 5.7, "Additive operators", paragraph 5 specifies this - the result of the addition itself is undefined; the program isn't valid even if you never dereference the pointers.

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.

It's highly unlikely to segfault even though it's allowed to, but it's still undefined with all that entails.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
4

If just assigning an invalid reference to a pointer were a problem, initializing one to NULL would also be a problem. So the answer to your specific question is 'no'.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
  • 1
    I believe, there is actually a difference between invalid pointer and null. And I believe, there is some ambiguity in standard which allows someone eager to read it in such a way that simply making a pointer invalid would trigger undefined behaviour (something along the line of non-defined term 'use'). However, I am no language lawer and can't argue this case. – SergeyA Jan 08 '16 at 15:33
  • The null pointer is a valid pointer value. ("A valid value of an object pointer type represents either the address of a byte in memory (1.7) or a null pointer" -- 3.9.2 Compound types.) – molbdnilo Jan 08 '16 at 15:51