0

Ok a very basic question, but I am stuck at it. I cannot figure out the extra mysterious value at the end of the array. I just tried to traverse the array through its base address, plain and simple. But the garbage value at the end of the array remains constant every time I execute it

g++ complier 64 bit machine.

#include<iostream>
#include<bits/stdc++.h>

using namespace std;

void printarray(int * arr){
   while(*(arr)){ cout<<*arr<<" "; arr++; }
   cout<<endl; 
}

int main(){
   int arr[] = { 3,2,4,1,5 };
   printarray(arr); // prints 3,2,4,1,5,32765
   return 0;
}

EDIT 1: I understand that the while will terminate whenever it comes across a 0 in the array , or if no 0 is found will go insane . But still I would want you guys to look at the following test cases

3,2,0,4,1,5  // outputs 3,2
3,2,4,1,5,7,8,9 // outputs same array correctly
3,2,4,1,5,7,8,9,10 // outputs array+ 1 varying garbage at last

//observations, this method works for even sized arrays not containing              
//0, while for odd it emits an additional garbage value.

My question is if the while only breaks at 0 , why does it break at
arrayLength+1 everytime ? Also what's with this even odd length ?

3
  • 1
    Did you debug it statement by statement? Commented May 9, 2016 at 13:42
  • while(*(arr)) why do you use this? At the point you reached the end of the array it is too late already and your code if already off to crazy wonderland (aka undefined behaviour) Commented May 9, 2016 at 13:42
  • 1
    while(*(arr)) expects a zero terminated array, but your's isn't. You are accessing that array out of bounds until the next arbitrary 0 is found. Commented May 9, 2016 at 13:43

4 Answers 4

5

An array is not terminated in any special way. What you are trying to do is not working because while(*arr) relies on a wrong assumption: that there is a 0 element at the end of the array (a sentinel) but you declare the array a {3,2,4,1,5} so there is no end element.

I think your misconcept comes from the fact that you are not getting the point that an int* is just a memory address, whenever you increment it by ++arr you are basically adjusting it by sizeof(int). Nothing more, when you reach the end of the array then the address just points after the array, to whatever value could be there.

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

Comments

2

You get the extra element(s) because there is nothing about a pointer that tells the compiler how many elements the pointer points to. When you do

while(*(arr)){...}

The while loop will continue running untill *arr == 0. Since you array doesn't contain a 0 it will keep going past the end of the array untill it finds a 0. This is undefined behavior as you are accessing memory you do not own with that pointer.

I think you may be confusing how char arrays(c-strings) work compared to other data types. When you have

char arr[] = "something";
while(*(arr)){...}

This ends at the end of the array as c-strings get a null terminator(0) added to the end of the string automatically. This allows you to do things like the above loop as you know that null terminator will be there and if it is not then that is on the person you created the string.

Comments

1

An array decays into a pointer when passed to a function, and this function knows nothing about the array's length.

That while(*arr) stuff is incorrect. It will stop only when some value this pointer points to is zero. But who said a zero is placed at the end of an array?? When you increment arr, you can easily get out of bounds of your array (the function doesn't know its size!), and then *arr will give you whatever the heck is stored at the memory address arr points to at the moment.

To iterate over an array, pass the array itself and its length. Otherwise this will iterate over and over until the value of *arr will be zero.

Comments

0

Pointers aren't terminated in C++ by any character. This works on other types like char* only because it's terminated by an \0(0).

An INT-Array u need to count the Elements before you can pass them into something like that, for example here with the ending 5 from your Pointer:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void printarray(int * arr){
    int *saved=arr;
   while(*saved!=5)
   { 
    cout<<*saved++<<" ";  
   }
   *saved=0;
   cout<<endl; 
}

int main(){
   int arr[] = { 3, 2, 4, 1, 5 };
   printarray(arr); // prints now without ending 5.
   return 0;
}

Otherwise, you need to pass the counter of elements. There is no way C++ could know how many elements your pointer points to.

Comments

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.