Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are there C++ algorithms defined specially for uninitialized memory?

Tags:

c++

Why do we need special algorithms to write to uninitialized (but allocated) memory? Won't the normal modifying algorithms do? Or does uninitialized memory mean something different from what the name itself conveys?

like image 544
Jeenu Avatar asked Jun 15 '21 19:06

Jeenu


Video Answer


3 Answers

Take std::copy and std::uninitialized_copy for a range of std::strings.

Regular copy will assume there already exists a string there. The copy assignment operator of string will try to use any existing space in the string if possible for the copy.

However, if there wasn't already a string there, as in the case of an uninitialized memory, the copy assignment operator will access garbage memory and behavior is undefined.

Uninitialized copy on the other hand will create the string there instead of assigning to it, so it can be used in a memory that does not already have a string in it.

Essentially, the regular versions will have a *it = value; in them, and uninitialized versions will have something like a new (&(*it)) T(value);.

like image 165
Fatih BAKIR Avatar answered Oct 08 '22 18:10

Fatih BAKIR


It is essentially about the object lifecycle.

After memory is allocated, it must be initialized by running the class' constructor. When the object is finished with, the class' destructor must be run.

The standard algorithms assume they are always accessing initialized memory and so objects can be created, copied, swapped and moved and deleted etc... based on that assumption.

When dealing with uninitialized memory however, the algorithms have to make sure they do not run a destructor on memory that was never initialized with the constructor. They have to avoid moving and swapping with non-existent objects by initializing the memory first when needed etc...

They have to deal with the extra step in the object lifecycle (initialization) that is unnecessary with already initialized memory.

like image 2
Galik Avatar answered Oct 08 '22 17:10

Galik


It's the difference between construction and assignment:

struct foo { /* whatever */ };
foo f;

unsigned char buf[sizeof foo];
foo *foo_ptr = (foo*) buf;
*foo_ptr = f; // undefined behavior; *foo_ptr does not point at a valid object
new (foo_ptr) foo; // okay; initializes raw memory
*foo_ptr = f; // okay; assignment to an existing object
like image 2
Pete Becker Avatar answered Oct 08 '22 17:10

Pete Becker