1

Even though the following piece of code compiles and runs fine i want to know if it is a valid c++ code?

int main()
{
        int *i= new int;
        cout<<*i;

        int &ref=*i;
        cout<<ref;

        delete &ref; //Especially is this statement valid?
        return 0;
}

If it is valid then this must also be valid :

int& getInt() {
    int* i = new int;
    return *i;  // OK?
}
int main(){
    int& myInt = getInt(); // these two lines are same as shown in the example above ?
    delete &myInt;   //is this OK too?
}
anurag86
  • 209
  • 1
  • 3
  • 9

1 Answers1

3

It's correct code and it will work on all platforms and compilers.

However, it's probably not best practice as the reference is usually used when the called party retains the ownership of the object.

Zbynek Vyskovsky - kvr000
  • 18,186
  • 3
  • 35
  • 43
  • Do you mean "**return by** reference is usually used when the called party retains ownership"? – harmic Feb 01 '17 at 05:17
  • In this link the accepted answer mentions its evil, which i couldnt understand hence posted this question : http://stackoverflow.com/questions/752658/is-the-practice-of-returning-a-c-reference-variable-evil Why does it mention that its evil? – anurag86 Feb 01 '17 at 05:18
  • 1
    I think the problem is that the memory management is unnatural. You allocate memory with `new` in `getInt()` and return the value of the integer, not its address. This is already a trick because otherwise i would just run out of scope. In main you have to be careful 1. to have the `int&` as type of `myInt`, because otherwise you loose the address and can't delete anymore 2. remember to delete The idea of a function is to encapsulate code. The caller should not need to know how it is implemented. The above code bypasses the actual sense of a function – maow Feb 01 '17 at 05:41
  • @anurag86 It is not evil, but *can* be. Returning variable from a function's scope by reference is evil, but it is not for say a static or member variable, as you'll not into undefined behavior that easily – Rakete1111 Feb 01 '17 at 05:45
  • @maow: Yes i understand your points but _memory management is unnatural_ for us not for the program. It will always get deleted correctly. I still cannot find anything wrong with it – anurag86 Feb 01 '17 at 07:11
  • @Rakete1111 As long as what we are returning is not a reference to something on stack, i believe it should be ok. Correct? – anurag86 Feb 01 '17 at 07:13
  • @maow `getInt` returns by reference, not by value – M.M Feb 01 '17 at 08:57
  • @anurag86 there's a difference between "code that works" and "good code". This is not good code. – M.M Feb 01 '17 at 08:58
  • @M.M Let me rephrase what I was trying to say. If you write something like `int myInt = getInt();` then the rvalue would implicitly be dereferenced and you end up loosing the adress, thus you can not free the memory anymore. Or am I mistaken? – maow Feb 01 '17 at 10:44
  • @anurag86 Maybe we are not on the same page regarding what "evil" code is. According to the [C++-Faq](www.parashift.com/c++-faq-lite/big-picture.html#faq-6.15) it does not mean the code would not work. In fact it does. Its just much more difficult (and thus errorprone) than it has to be – maow Feb 01 '17 at 10:44
  • @maow `getInt()` is an lvalue . That code would cause a memory leak because the memory allocated by `new` is never deleted. – M.M Feb 01 '17 at 10:48
  • @M.M Thats my point. I think the code is evil, exactly because it's so easy to create a memory leak. – maow Feb 01 '17 at 10:52
  • @M.M how is `getInt()` a memoryleak even after `delete &myInt;` is executed? – anurag86 Feb 02 '17 at 14:36
  • @anurag86 the code `int myInt = getInt();` is a memory leak . `delete &myInt;` would be undefined behaviour because `myInt` was not allocated by `new`. – M.M Feb 02 '17 at 19:50
  • @M.M I can have `int *p1=new int;` and `int *p2=p1;`. Here `delete p2` is not UD. In our case myInt is a reference, still dont see why is it UD. Could you please explain – anurag86 Feb 03 '17 at 05:21
  • @anurag86 in the code `int myInt = getInt();`, `myInt` is not a reference. – M.M Feb 03 '17 at 06:29
  • @M.M It is a reference `int& myInt = getInt();` – anurag86 Feb 03 '17 at 06:33
  • @anurag86 this series of comments (starting with the comment by "maow") is about the code `int myInt = getInt();` , please read them more closely – M.M Feb 03 '17 at 06:49