c++delete() using a reference variable !

Q1: if you have nothing but a reference to a heap object, how can you delete it?
AA: yes. q(delete & theReference) works

Q1b: how about valgrind q(g++ -g d.cpp; valgrind ./a.out)?
AA: no leak.

See https://stackoverflow.com/questions/3233987/deleting-a-reference. q(new vector<int>) works but is code smell. Code smells tend to be useful tricks.

https://bintanvictor.wordpress.com/?p=10514&preview=true has details on vector memory allocation.

 // --- d.cpp ---
#include <vector>
#include <iostream>
using namespace std;

typedef vector<int> intArray;

intArray & createArray() {
    intArray *arr = new intArray(3, 0);
    return(*arr);
}

int main(int argc, char *argv[]) {
    intArray& array = createArray();
    for (int i=0; i< array.size(); ++i){
      cout<<array[i]<<' ';
    }
    intArray * ptr2ref = & array;
    delete ptr2ref;
}

c++return by ref, briefly

Background: This is an old topic I studied multiple times, but still unfamiliar. I think most people don’t work at such a low level?

Q1: Can return a malloc object by reference? I doubt it. I think the address is lost and there’s no way to free it.

Q1b: if you only have a reference to a heap object, how can you delete it? See https://bintanvictor.wordpress.com/?p=10505&preview=true

Q: Can return a static local by reference? I think so but not popular

Q: Can return a by-ref argument by reference? No need (but legal) since the caller already has that reference. You could return it in an if/else

Q: can return another object in scope by reference? Yes

Return-by-non-const-ref is often used in operator overloading to support counter[3].increment()

The assignment operator returns a const ref.

 

returning const ptr: useless#with test program

I agree with an online post. Returning a const ptr is same as returning a non-const ptr. Caller would clone that const ptr just as it clones a mutable ptr.

I would say what’s returned is an address, just like returning an int value of 315.

int i=444;
int * const pi = &i;
int * p2 = pi;
int main(){
  int i2=222;
  p2 = &i2;
  cout << *p2 <<endl;
}

It does make a difference if you return a ptr-to-const. The caller would make a clone of the ptr-to-const and can’t subsequently write to the pointee.

pointer as field –#1 pattern in c++

This mega-pattern is present in 90% of java and c# classes!

Three related choices for a member variable:

  • Raw pointer
  • Smart ptr
  • char pointer, usually a c-str

In each case, we worry about

  • construction of this field
  • freeing heap memory
  • RAII
  • what if the pointee is not on heap?
  • copy control of this field
  • ownership of the pointer
  • when to return raw ptr and when to return a smart ptr

 

illegal to assign rvalues into non-const Lval-ref

This is a tough one for the average cpp guy

int& myint = getInt(); // illegal, since getInt() returns a nonref.

(What if getInt returns a reference??? . I think it’s legal.)

However, adding a const makes it legal:

int const & var1 = 33;

In fact, this is same thing as the (extremely) common idiom of using const ref as function param. With that, you can pass in either an lvalue (like a literal) or rvalue.

I found the above exlanation on
http://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c . The author (Eli) points out:

* subtle difference between const lval-ref vs non-const lval-ref (above) * lvalue means “locator value”
* a concise example of mv-semantics
* An everyday example of a function returning an lvalue is operator[] in

myMap[10] =5.6

pointer equality – counter-intuitive in c++

label – ptr/ref, book

Background: Pointer (identity) comparison is widely used in java, c# and python. 
[[c++common knowledge]] points out that if class DD subclasses CC and BB (classic MI), then pointer d, c, b follows:
assert(d == c); // since the the pointer to DD object can be cast to pointer to CC
assert(d == b); // since the the pointer to DD object can be cast to pointer to BB
However, c and b are two different address, because the 2 sub-objects can't possibly have the same starting point in the address space.

mv-semantic n RVR – %%Lesson #1

#9 std::move()
#8 STL containers using mv-semantic — confusing if we don’t have a firm grounding on …

#7 mv ctor and mv assignment — all the fine details would be poorly understood if we don’t have a grip on …

#5 RVR — is a non-trivial feature by itself. First, we really need to compare…

#3 rval expression vs lval expression — but the “expression” bit is confusing!

#1 lval expression vs lval variable vs objects in a program
This is fundamental concept.

RVR – exclusively(?) used as function parameter

RVR – exclusively(?) used as function parameter

There could be tutorials showing other usages, like a regular variable, but i don’t see any reason. I only understand the motivation for
– move-ctor/move-assignment and
– insertions like push_back()

When there’s a function taking a RVR param, there’s usually a “traditional” overload without RVR, so compiler can choose based on the argument:
* if arg is an rval expression then choose the RVR version [1]
* otherwise, choose the traditional

[1] std::move(myVar) would cast myVar into an rval expression. This is kind of the converter between the 2 overloads.

In some cases, there exists only the RVR version, perhaps because copy is prohibited… Perhaps a class holding a FILE pointer?