Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are heap allocated member references a terrible idea? Why?

To best explain this problem, I have constructed a simple example. Say I have a class Blob as follows:

class Blob
{
    string personalName;
    string& familyName;
}

A Blob can be spawned by the Creator (aka Programmer), at which point it gets to pick a personalName and, since it has the privilege of being a 1st generation Blob, it gets to pick it's own familyName.

Alternatively, a Blob can be created by spawning off an existing Blob, at which point it picks its own personalName, but shares a familyName with all other Blobs that have been cloned in this family. If one Blob changes the family name, all other family members get that name change automatically.

So far, this sounds all well and good, until when writing the Blob constructor I see this:

Blob::Blob() :
    personalName(pickName()),
    familyName(pickFamilyName())
{ }

...

string& Blob::pickFamilyName()
{
    return *(new string("George"));
}   // All Blobs have family name "George" in this example

Eek! Allocating memory on the heap then assigning it to a reference variable?! That looks scary!

Are my instincts correct that there is something very wrong with this, or does it only feel strange to me because it is not a common pattern? If there is something wrong, what is it? Why is this a bad design?

Note: It would be important to free that heap-allocated memory by reference counting and deleting the memory when the last Blob is destructed, or by some other method.

like image 721
Cory Klein Avatar asked Aug 23 '11 20:08

Cory Klein


People also ask

Can references point to the heap?

Heap references are always memory-preserving, which means that, as long as a heap reference points to an object or a part of an object, the object is not deleted by Garbage Collector.

What is heap allocated?

Heap Allocation: Heap allocation is an allocation procedure in which the heap is used to manage the allocation of memory. Heap helps in managing dynamic memory allocation. In heap allocation, the creation of dynamic data objects and data structures is also possible as same as stack allocation.

Is memory allocated for reference?

Memory is allocated when a pointer is defined. A reference however, is a name alias & hence no memory is allocated for it( Is it correct? ). 2. Reference is bound to be initialized at the time of definition because, a reference is implemented with a constant pointer & hence cannot be made to point to the other object.

How does heap allocation work?

Heap follows dynamic memory allocation scheme (memory is allocated during execution or at runtime) and provides random and global access to objects created, unlike stack, which follows Last-In-First-Out (LIFO) memory access order. The size of heap memory is large when compared to stack.


2 Answers

The only time it makes sense to store a reference as a class member is when:

  1. The data is not owned by the class and the class is not responsible for freeing it;
  2. The lifetime of the referred object is guaranteed to be longer than the lifetime of the containing object.

Your example violates rule 1.

like image 53
Mark Ransom Avatar answered Nov 10 '22 00:11

Mark Ransom


I think the "smelly" part of it is storing the variable as a reference to a string, since it can become difficult to keep track of whether it's a valid object. Why not use something like:

boost::shared_ptr<std::string> Blob::pickFamilyName()
{
    return boost::shared_ptr<std::string>(new std::string("George"));
}

EDIT

As per Praetorian's suggestion, you can avoid manually allocating memory yourself altogether:

boost::shared_ptr<std::string> Blob::pickFamilyName()
{
    return boost::make_shared<std::string>("George");
}
like image 38
Dawson Avatar answered Nov 10 '22 01:11

Dawson