0

I'm new to c++ and as an exercise trying to print an array using a function. I created two arrays arr and arr2 as following.

int main(){

int arr[5] = {11, 12, 13, 14, 15};

int i =1;
int* arr2 = &i;
*arr2 =1;
*(arr2+1) =2;
*(arr2+2) =3;
*(arr2+3) =4;
*(arr2+4) =5;

printArray(arr2,5);    
printArray(arr,5);
}

I'm trying to print those two arrays using the function below.

void printArray(int arr[],int size){
   for(int i=0; i<size; i++){       
      cout<<*(arr+i)<<" ";
   }
   cout<<endl;
}

The result after running the program is,

 1 2 3 4 5
 2 3 4 5 15

But the expected result is,

1 2 3 4 5
11 12 13 14 15

Can someone explain what is happening here, If it is a problem with memory allocation highly appreciate if you can explain with a proper diagram.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
e11438
  • 864
  • 3
  • 19
  • 33
  • 5
    You have *undefined behaviour*. `arr2` doesn't point to a block of 5 `int` but just one `int`. So, `*(arr2+1) =2; *(arr2+2) =3; *(arr2+3) =4; *(arr2+4) =5;` all access outside of the bounds. The same problem persists when print `arr2` in `printArray()` function. – P.P Dec 14 '16 at 13:00
  • 2
    This is undefined behavior – Cory Kramer Dec 14 '16 at 13:01
  • 2
    As already pointed out this is UB and apparently your compiler decided to allocate `i` right before `arr` so that `(arr2 + 1) == &arr[0]` - but this is in **NO** way correct or guaranteed (different compilers or just changing optimization level might already cause completely different effects) – UnholySheep Dec 14 '16 at 13:04
  • Why C++ and DMA tags, when you have not used any of them. This code will have same undefined behavior even in C. – Bharath Dec 14 '16 at 13:10
  • @programmerDaemon: C and C++ are different languages. OP uses C++, so the C++ tag is correct. The C tag is wrong! The C standard has a defect for exactly this situation, which was already discussed here. – too honest for this site Dec 14 '16 at 13:20
  • 2
    Don't use C-style arrays, use `std::vector` and `std::array`. – n. m. could be an AI Dec 14 '16 at 13:21
  • "I created two arrays `arr` and `arr2`" - no, you didn't. You created one array and one pointer. There is a list of good books [here](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – molbdnilo Dec 14 '16 at 13:52

3 Answers3

3

The variables you are declaring are declared on the stack:

int arr[5] = { 11, 12, 13, 14, 15 }; // 5xsizeof (int) bytes
int i = 1; // sizeof (int) bytes on the stack
int *arr2 = &i; // sizeof (void*) bytes on the stack

Now arr2 is a pointer to an int. In another context it could be a pointer to a dynamically allocated array, but here, it's not: it is pointing to the location of i on the stack. When you do:

*(arr2 + 1) = 2;

You are assigning 2 to another address on the stack (the one that comes right after &i) and from your result it looks like it coincide with the address of arr[0], which is kinda logical (but well since it is undefined behavior, anything could happen).

Since you are assigning to addresses on the stack, you don't get a segfault but you do corrupt the stack however, which is much worse than getting a segfault:

  • A segfault is a clear signal telling you you are trying an illegal memory access. You know where it takes place and you can fix it.
  • Stack corruption happens silently and can go unnoticed until it crashes the program, which could happen anywhere. It is the result of an "illegal" memory access that goes undetected because the stack is already reserved for your program. Of course, debugging it is very hard since the crash can happen in a place that is completely unrelated to the faulty code.
Rerito
  • 5,886
  • 21
  • 47
  • "much worse than getting a segfault" I would suggest that a segfault is one of the *best* symptoms of UB to get, because it so loudly tells you things are wrong, and where to start looking – Caleth Dec 15 '16 at 09:38
  • @Caleth Which is exactly why I said a silent stack corruption is much worse than a segfault. Maybe you mean to rephrase it to make look a segfault as a positive thing? – Rerito Dec 15 '16 at 09:46
  • Yes. Silent stack corruption -> ignored/not noticed -> bug in production. Segfault -> identified -> fixed – Caleth Dec 15 '16 at 09:51
2

arr2 is not an array. It is pointer to int i. You are reading from memory that is not yours.

Instead, use:

int* arr2 = new int[how_long_array_you_want]

Do not forget to delete arr2.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Schrami
  • 89
  • 1
  • 12
-2

wow no sigsegv? Just a combination of factores, probably (inside the machine) the variable i get declared before the array. So you cannot do it. the variable "i" allocate just a slot for an integer. but you need 5. when you do *(arr2+1) you are going to write in a ungulty,neighbour random variable. In this case proably the arr[]. Luckily is also an integer, otherwise you are going to get a SIGSEGV error So the code is going to be

int i[5];
int *arr2=i;

so it works

jurhas
  • 613
  • 1
  • 4
  • 12
  • *"Luckily is also an integer"* - no... just because you point a pointer to an adress does not mean that some underlying data type has to be present there. Also it doesn't *work*, it's undefined behavior that just happens to have this exact effect on OPs machine and compiler – UnholySheep Dec 14 '16 at 13:11
  • Segfault has nothing to do with the underlying type of the attempted access. Here it does not segfault because each `arr2 + i` points to memory on the stack. – Rerito Dec 14 '16 at 13:13
  • *"Luckily yhe pointer fall inside your heap"* except it doesn't, the pointed to address is on the stack. – UnholySheep Dec 14 '16 at 13:25
  • You are right. The world,like the memory divide him self at least in two categories. Those who know the name of the memory and cannot use it, and those that doesn't know their name, but can use it. I just call it the memory allocated of the program compiling time. The other is the memory dinamically. How in China call the one or the other never cared about... Please check for my typo now. – jurhas Dec 14 '16 at 13:33
  • 2
    This answer is unclear at best, when it's not just plain wrong. As is, it deserves its downvotes. – Rerito Dec 14 '16 at 13:33