1

In my header, I declared a few variables as @property (nonatomic) NSInteger *soldWindows; and used them to keep track of counts, incrementing with _soldWindows++;. The result consistently came out 8 times what it should be. I figured out my problem was declaring it as a pointer, so I changed it to @property (nonatomic) NSInteger soldWindows; which solved my problem.

My question is, if it was just storing a memory address, why was the integer value scaled by 8 instead of being an arbitrary address?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Joe
  • 33
  • 1
  • 8
  • 1
    Besides the correct answer by ChrisCM, there does not seem to be a particular reason why you would be using an NSInteger. So simply use an int intead. – fishinear Oct 15 '15 at 13:36
  • 1
    @fishinear Depending on the target an `NSInteger` is a typedef to either `int` or `long`. So what's the benefit switching to `int`? – Nikolai Ruhe Oct 15 '15 at 13:48
  • 3
    @fishinear Bad advice. – rmaddy Oct 15 '15 at 13:56
  • 1
    Keep it down guys, this is a matter of style, and not very important style, so the strong response is a bit over the top. The variable mentioned "soldWindows" - that is, "the number of sold windows" - does not seem to have anything to do with Apple's API's for which NSInteger was introduced. Therefore, it can be confusing to use that type, rather than a normal C type. – fishinear Oct 15 '15 at 14:18

2 Answers2

5

A pointer points to a place in memory. When you increment a pointer like this, you increment the value of the pointer, to point to a new place in memory. Given this, you can use pointer arithmetic to iterate through successive elements in an array, by dereferencing an incremented pointer. So, you're not incrementing by 1, but rather, by the size of the type of your pointer. An NSInteger is nothing more than a 64 or 32 bit int, depending on platform. In this case, it seems to be 64 bits, which is 8 bytes. This is where your 8 bit "scaling" was coming from.

Conclusion: your fix is correct!

MobA11y
  • 18,425
  • 3
  • 49
  • 76
  • Your explanation is correct. The example is rather confusing (and—if meant as actual code—wrong). – Nikolai Ruhe Oct 15 '15 at 14:23
  • 1
    "When [...] you increment the place in memory that it is pointing to" sounds like the pointee is incremented, not the pointer. That would be wrong. The address in the pointer is incremented, not the place in memory. – Nikolai Ruhe Oct 15 '15 at 14:56
0

I declared a few variables as [...] NSInteger *soldWindows; and used them to keep track of counts.

You are misusing the concept of a pointer. In C, a pointer is the address of an object in memory. In your use case there is no object being pointed to—just the address that point's to nowhere.

While this is not a problem as long as you don't dereference the pointer it's still confusing (and does not help in any way). A simple integer (like int or NSInteger) is a better choice.

why was the integer value scaled by 8?

The reason for this is called pointer arithmetic. Every C pointer has a type. The type describes the object in memory where the pointer holds the address of. When you increment a pointer, the compiler actually adds the size of the object to the pointer, so that it points to the object right after the previous one.

The size of NSInteger (in 64 Bit iOS) is 64 bit = 8 bytes. That's why incrementing an NSInteger * actually adds 8 to it.

Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200
  • 1
    @ChrisCM I assume the OP is using the pointer for its value (probably initialized to `NULL` or so). He's seeing the value increment in steps of 8, so he's using the pointer value as an integral scalar value. I don't think he's ever actually pointing to something (apart from a random address in virtual memory, that's what I meant with "nothing"). Dereferencing the pointer would be undefined behavior. – Nikolai Ruhe Oct 15 '15 at 14:52