0

I am trying to loop through an array of integers using pointers using the following code:

#include <iostream>

int main (int argc, char ** argv)
{
    int ar[] = {1,1,2,3,5,8,13,21,34,55};
    char s[] = "string";

    std::cout << "Print fibonacci until ten using pointers" << std::endl;
    for (int * p = ar; *p; p++)
    {
        std::cout << *p << std::endl;
    }

    //  for (char * cp = s; *cp; cp++)
    //      std::cout << "char is " << *cp << std::endl;

    return 0;
}

On running this code, I get all 10 elements plus a number, 4196368. But on uncommenting the second for-loop and running it again, the numbers vanishes.

Can someone explain why this happens? If needed, the code is compiled in a 64-bit Linux box.

Rudra
  • 53
  • 7

4 Answers4

3

You're lucky the loop stopped at all; you could have blown up your entire neighbourhood!

Your loop expects to find a "zero" to terminate the array iteration, but your array doesn't have one. Thus, your loop will just keep incrementing past the end of the array until god knows what. The practical results depend on too many practical factors to be either predictable or usefully explained.

I presume that this is an exercise, because using "null-termination" to iterate over an int array is mighty peculiar. In reality you'd just write:

for (auto x : ar)
    std::cout << x << '\n';
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Is there any significance to the number? Normally pointer errors spit out random numbers from what I've tried. – Rudra May 06 '16 at 11:42
  • @Rudra: They're never _random_; they're generally "whatever happens to be at that place in memory". The thing is that computers are so very complicated that attempting to determine _why_ that particular value happens to be at that particular place in memory would take far more effort than is useful. So, instead, we just stick to the abstractions defined by the language spec, and say "we could have seen any arbitrary number, or number, or a cat emoji, or a flying electric turnip" to really drive home that if you go past the end of your array you've given up all reasonable rights to logic. :) – Lightness Races in Orbit May 06 '16 at 11:44
  • @Rudra: It's important to remember that compilers are much more complex than those made in the 1970s (which many Stack Overflow answers sadly accidentally rely on) with lots of clever algorithms to make your program as fast as possible. Those algorithms make use of the assumptions the standard guarantees, like "a valid program will not go past the end of an array". That's why instead of an arbitrary/unexpected value, you really could have seen all sorts of strange effects. On SO we tend to employ hyperbole to pretend that "opening a black hole" is one such possibility. – Lightness Races in Orbit May 06 '16 at 11:50
  • (though if you have a computer powerful enough to trigger such an event I'd love to borrow it for the day :P) – Lightness Races in Orbit May 06 '16 at 11:50
2

You are invoking an undefined behavior.

The first for loop's termination condition is *p. So it is trying to access memory past what actually is owned by ar. Your loop then runs until it finds a memory location that contains 0 (read false) before terminating. In your case, it ran just one extra time (lucky you!). At my end, it ran four more times before terminating.

You must loop only as many times as the size of the array, which is sizeof(ar)/sizeof(ar[0])

Community
  • 1
  • 1
CinCout
  • 9,486
  • 12
  • 49
  • 67
0

Ensure that you have terminated zero:

int ar[] = {1,1,2,3,5,8,13,21,34,55, 0};
AnatolyS
  • 4,249
  • 18
  • 28
0

Well, actually this will result in a different outcome on a different machine or a different condition. The one that causes this is your for statement

for (int * p = ar; *p; p++)
{
    std::cout << *p << std::endl;
}

Here, you used *p as a conditional for your for loop to keep running. As we know, C++ treat number > 0 as a true and 0 as a false. While in the for statement, your program checks the next memory address if the value in that address is zero or not (True or False). And as you know, the value of the next address in this particular case on your particular PC is 4196368. So the for loop keeps going until the value of the next address is zero. You can see this with printing the address.

for (int * p = ar; *p; p++)
{
    std::cout << *p << " " << p << std::endl;
}

You will know here that your code check the next address to see its value an if it is indeed not zero, it will continue the loop.

AchmadJP
  • 893
  • 8
  • 17