0

The function f1 creates an instance of foo and sets foo.ptr[0] = 2.

#include <iostream>
using namespace std;

class foo {
public:
        int *ptr;
        inline foo(int a) {
                ptr = new int[a];
        }
        inline ~foo() {
                delete[] ptr;
        }
};
foo f1() {
        foo a(5);
        a.ptr[0] = 2;
        return a;
}
int main() {
        foo a = f1();
        cout<<a.ptr[0]<<endl;
        return 0;
}

What I expected as the output: junk value.

f1 returns by value, which means a copy of a is made and this copy even shares the same memory locations at which their (a and it's copy) respective ptrs point at.

Outside f1, a gets destroyed. It's destructor is called which will deallocate ptr's memory. This means the memory location which the copy's ptr points at is also invalid. So, I expect a junk value as output.

The output actually is 2.

Why?

batman
  • 5,022
  • 11
  • 52
  • 82
  • 4
    It's undefined behaviour. You're calling `delete[]` on an already freed memory location. – chris May 18 '13 at 18:58
  • Your expectations are tantamount to relying on a defined outcome, and there is no such beast with undefined behavior. For some insight on what all these references to undefined behavior really mean, [see this q&a](http://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior). – WhozCraig May 18 '13 at 19:07
  • @chris, Already freed memory location? I thought whenever an object goes out of scope, it's destructor gets called. Now, the destructor here uses `delete` to free the memory allocated to `ptr`. Right? – batman May 18 '13 at 19:09
  • @learner, Yes, the object in the function is destroyed and the memory freed. Then, there's a theoretical copy to `a` in `main`, so the returned one might get destroyed as well, and then the one in `main` is destroyed. They all share the same pointer, and there's only one `new[]`. – chris May 18 '13 at 19:12
  • @chris, Ah, you meant `You're calling delete[] on an already freed memory location` **when the program terminates** (the object declared in `main` function goes out of scope), right? – batman May 18 '13 at 19:19
  • @learner, Yes, that's what I meant, along with the possibility of when `main`'s `a` is constructed if the compiler so chooses. – chris May 18 '13 at 19:22
  • @chris, sorry for being persistent. But how will that possibly happen during construction? Construction here means using the implicit copy constructor, which will simply copy every member. Will `delete` get used at all at the point of construction? – batman May 18 '13 at 19:26
  • 1
    @learner, The function returns a temporary value, the main one is copy-constructed from it, and the temporary is destroyed. A compiler could choose to elide that copy, though. – chris May 18 '13 at 19:29

1 Answers1

3

The standard never says that you should expect a "junk value". Instead, it says you'll get undefined behaviour. Since you are not following the rule of three (or five), the dynamically allocated array of ints is destroyed when f1 returns and the object a ends up with a pointer to the destroyed array. To access this gives you undefined behaviour.

The reason you're likely seeing the value 2 is because that memory location hasn't been reused since the value 2 was in there. However, reasoning about this is meaningless as far as the standard is concerned.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324