2
votes

I created an array of simple Dummy objects on the stack:

    Dummy a(8);
    Dummy b(9);
    Dummy dummies[2] = {a,b};

There is a MyObject object. I created it on the stack. The constructor stores this array into an instance variable.

    class MyObject{
        Dummy* _dummies;

        MyObject obj(Dummy* dummies):
        : _dummies(dummies)
        {
        }
    };

    MyObject obj(dummies); 

When obj is removed and its destructor is called is the memory of _dummies freed? I understand that instance variables on stack are freed automatically, but how does MyObject know that this pointer points to an array on the stack and not to a Dummy object created on the heap?

In the constructor is the dummies array passed by value or reference? It is a pointer, but it is an array on the stack after all.

I understand stack, heap, passing by value and reference, but arrays on the stack handled with pointers really confuse me. I have always used vector, because it is clear and simple, but I would like to understand simple arrays too.

EDIT: thank you all. Now I understand that MyObject doesn't have anything to do with the array's lifetime. When dummies array is out of scope it gets removed.

BUT: what if "Dummy" is replaced with "char"? It is quite standard to have a char* on the stack (returned from a function for example), and pass it to an object, which then stores it simply by saving the pointer to the first char. Is that one a bad practice too? (I am going to use std::vector and std::string instead, much simpler...)

5
Did you "new" anything? If not, not need to worry. - Lawrence Aiello
unless u created the memory by "new", there is no need to worry about freeing it. When it goes out of scope it will be popped off the stack. - ivanw
The array as such isn't passed to the constructor at all. The constructor receives a pointer to the first element of the array. - molbdnilo

5 Answers

1
votes

You need to be aware that your instance variable _dummies is just a pointer. When you create the object, a pointer that is passed to the constructor is stored into _dummies, that's all. That pointer could be NULL, the address of an array on the stack, a pointer returned by malloc, or many other things. Your object doesn't know.

If the array disappears while the object still exists, you are in trouble if you use the object after that. You are responsible that the array still exists until the last time that _dummies in the object is accessed. And you are responsible for deleting the array itself in some way after the object goes away. So your construct is slightly on the dangerous side and will crash unless you use it carefully.

0
votes

The only concern you have is if you used new in your Dummy class. If you didn't, no need to be concerned. When objects on the stack go out of scope, they get deleted automatically.

0
votes

When obj is removed and its destructor is called is the memory of _dummies freed?

No, but that's not a problem, if I understand your example correctly, because the 'memory of _dummies' is on the stack and will be freed when it goes out of scope (independently of the MyObject instance being destroyed).

I understand that instance variables on stack are freed automatically, but how does MyObject know that this pointer points to an array on the stack and not to a Dummy object created on the heap?

It doesn't. As I said above, the MyObject destructor won't automatically free any allocated memory that _dummies points to.

In the constructor is the dummies array passed by value or reference? It is a pointer, but it is an array on the stack after all.

It is an array on the stack, not a pointer. When used in an expression it 'decays' to a pointer (which points to the first element in the array). Therefore, it is passed by reference (but not as a C++ reference!).

0
votes

Your Dummy* _dummies; member variable may or may not point to some actual memory location. Managing this location is your responsibility, not default constructor's. So, if you initialize it with a pointer that comes outside your class, when the instance is destroyed, nothing will happen to the memory pointed to, just the pointer will disappear. If you create (new) an instance in your class, you must release (delete) it in destructor.

From practical point of view, you might want to consider smart pointers, such as std::shared_ptr in C++11 to make these tasks less error prone.

0
votes

When obj is removed and its destructor is called is the memory of _dummies freed?

No, it isn't. If you want to free memory associated with any pointer you have to do so explicitly e.g. by typing delete[] _dummies if _dummies is an dynamic array.

how does MyObject know that this pointer points to an array on the stack and not to a Dummy object created on the heap?

It doesn't. It means that if you try to access _dummies in MyObject after the stack-allocated Dummy dummies[2] = {a,b}; go out of scope and get deleted you might get a segfault.

In the constructor is the dummies array passed by value or reference?

Its type Dummy[] is coerced to a pointer type Dummy*, which then is passed by value.