Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the output of the following code snippet? What does it mean?

Tags:

c++

I'm studying for a C++/OOP exam and am a little confused with this question on my practice test.

What is the output of the following code snippet?

int *list = new int[5];
int *ptr;
for (int i = 0; i < 5; i ++)
list [ i] = i+ 1;
ptr = list;
delete [ ] list;
cout << *ptr
  1. 1
  2. Address of list
  3. Address of ptr
  4. Error – ptr references memory that no longer belongs to the program

I found the output, which is -17891602, but am I correct in assuming this is just a reference to memory that no longer belongs to the program? Because I'm not necessarily getting an error.

It's been a while since I worked with pointers, so I'm getting a but twisted up trying to follow what the code is actually doing. (I know it's simple compared to some stuff you guys are working on, but I'm just getting started learning this stuff :) )

like image 478
arsis-dev Avatar asked Nov 19 '25 21:11

arsis-dev


2 Answers

The output could be anything (including -17891602) since you're invoking undefined behaviour by dereferencing a pointer that has had its backing memory deallocated.

The relevant part of the standard is C++11 3.7.4.2 Deallocation functions /4 (my bold):

If the argument given to a deallocation function in the standard library is a pointer that is not the null pointer value, the deallocation function shall deallocate the storage referenced by the pointer, rendering invalid all pointers referring to any part of the deallocated storage. The effect of using an invalid pointer value (including passing it to a deallocation function) is undefined.

On my system, the following program (modelled on your snippet):

#include <iostream>

int main (void) {
    int *list = new int[5];
    int *ptr;
    for (int i = 0; i < 5; i ++)
        list [ i] = i+ 1;
    ptr = list;
    delete [ ] list;
    std::cout << *ptr;
    return 0;
}

outputs 1 but it is by no means required to.

The correct answer to your question is most likely 4, though that's not technically the output (you may not see the "error" string sent to the output stream) - it is, however, the result of executing the code.

like image 50
paxdiablo Avatar answered Nov 22 '25 12:11

paxdiablo


I wasn't going to weight in on this, but HostileFork's answer (which I +1ed) digs in while missing a couple points - too much to comment on easily, so here I am...

Firstly the question:

What is the output of the following code snippet?

For the code given, the output may be anything or nothing, which is not one of the answers. Still, the intended answer is obviously 4:

Error – ptr references memory that no longer belongs to the program

That said:

  • the memory probably still belongs to the program/process (most C++ implementations don't release memory used to satisfy small memory allocations to the OS until program termination), but it's no longer "owned" by the application-level code you've listed, as delete[] returns ownership to the memory allocation library

  • the problem is not just what ptr references, but specifically that ptr is being dereferenced while pointing to released memory

Summarily, the question is poorly worded, but the intent behind it is fairly clear.

I won't repeat the explanation of undefined behaviour that addresses your "Because I'm not necessarily getting an error." observation, as HostileFork's answer does that well.

Still, computer programs don't tend to go out of their way to do weird things arbitrarily, even when the compiler's not obliged by the C++ Standard to provide any particular behaviour, and in this particular case the observation I made above that the memory's likely still owned by the program, combined with noticing that the value of *ptr before delete[] list; executed must have been 1, leads to the question...

Why did you see -17891602 and not 1?

On a hunch I converted it to unsigned 32 bit hexadecimal (as one does): the value's then FEEEFEEE. Wikipedia says of this "magic number":

Used by Microsoft's debug HeapFree() to mark freed heap memory.

So, Microsoft's delete[] function triggered overwriting of the five int locations with 0xFEEEFEEE, intended to make it easier for you - the programmer - to see you had undefined behaviour. As overwriting the memory takes time while the programm is running, and is only helpful if the program's actually broken anyway which you'll hopefully realise and fix before making and distributing a "release" build, this FEEEFEEE-fill behaviour is only done in MS's "debug" builds. Other compilers or malloc libraries often offer similar behaviour enabled by compiler flags / environment variables etc..

like image 23
Tony Delroy Avatar answered Nov 22 '25 12:11

Tony Delroy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!