Search code examples
c++templatesinitializationcontainersdynamic-memory-allocation

Initializing an object with garbage data when there is no default constructor


I'm trying to allocate some objects on the HEAP since I am trying to design a "tree" data structure, which essentially is implemented as a linked list with an added pointer to the head of a child linked list. My problem is that I initialize the "trunk" of the tree (which is the single parent-most node in the tree) upon the construction of the tree.

I want to have a default constructor for the tree class since its a container class, but that becomes a problem when the data being held in the nodes of the tree does not have a default constructor. My initial idea was, as the title of this question suggests, to simply force the data of the node with garbage data by doing something like this:

template<class Ty>
Tree<Ty>::Node::Node()
    : parent(nullptr)
    , next(nullptr)
    , child_head(nullptr)
{
    const auto garbage_data_ptr = _malloca(sizeof(Ty));
    if (garbage_data_ptr)
        memcpy(static_cast<void*>(&data), garbage_data_ptr, sizeof(Ty));
    else
        throw std::exception("CANNOT ALLOCATE GARBAGE DATA FOR TRUNK");
    _freea(garbage_data_ptr);
}

Of course, the problem is that the data member still needs to be initialized in the member-initialization list. This is potentially doable, but I have no idea how to free the memory after I've requested it.

I'm also aware the above code probably is the worst way to go about this, so please let me know a better way to do this if at all possible.

Specifically, I'd like to know

  1. How to construct an object without a default constructor so the data can be modified later
  2. Or, if the above isn't possible, how to force an object to be full of garbage data which can be changed later

I know, in the case of an object that does have a default constructor, you just get the leftover memory before a value is assigned, as is the case with

int x;  // <-- Set to some "random" value from leftover memory
x = 10;  // <-- "random" value replaced with 10

Solution

  • If you are using C++17 or higher, instead of having an actual object stored, you could instead use std::optional. This allows for default-construction even if the underlying type isn't default-constructable, and this is way safer than copying garbage data onto an object. :-)