I hear talks of C++14 introducing a garbage collector in the C++ standard library itself. What is the rationale behind this feature? Isn\'t this the reason that RAII exists in
Definitions:
RCB GC: Reference-Counting Based GC.
MSB GC: Mark-Sweep Based GC.
Quick Answer:
MSB GC should be added into the C++ standard, because it is more handy than RCB GC in certain cases.
Two illustrative examples:
Consider a global buffer whose initial size is small, and any thread can dynamically enlarge its size and keep the old contents accessible for other threads.
Implementation 1 (MSB GC Version):
int* g_buf = 0;
size_t g_current_buf_size = 1024;
void InitializeGlobalBuffer()
{
g_buf = gcnew int[g_current_buf_size];
}
int GetValueFromGlobalBuffer(size_t index)
{
return g_buf[index];
}
void EnlargeGlobalBufferSize(size_t new_size)
{
if (new_size > g_current_buf_size)
{
auto tmp_buf = gcnew int[new_size];
memcpy(tmp_buf, g_buf, g_current_buf_size * sizeof(int));
std::swap(tmp_buf, g_buf);
}
}
Implementation 2 (RCB GC Version):
std::shared_ptr g_buf;
size_t g_current_buf_size = 1024;
std::shared_ptr NewBuffer(size_t size)
{
return std::shared_ptr(new int[size], []( int *p ) { delete[] p; });
}
void InitializeGlobalBuffer()
{
g_buf = NewBuffer(g_current_buf_size);
}
int GetValueFromGlobalBuffer(size_t index)
{
return g_buf[index];
}
void EnlargeGlobalBufferSize(size_t new_size)
{
if (new_size > g_current_buf_size)
{
auto tmp_buf = NewBuffer(new_size);
memcpy(tmp_buf, g_buf, g_current_buf_size * sizeof(int));
std::swap(tmp_buf, g_buf);
//
// Now tmp_buf owns the old g_buf, when tmp_buf is destructed,
// the old g_buf will also be deleted.
//
}
}
PLEASE NOTE:
After calling std::swap(tmp_buf, g_buf);
, tmp_buf
owns the old g_buf
. When tmp_buf
is destructed, the old g_buf
will also be deleted.
If another thread is calling GetValueFromGlobalBuffer(index);
to fetch the value from the old g_buf
, then A Race Hazard Will Occur!!!
So, though implementation 2 looks as elegant as implementation 1, it doesn't work!
If we want to make implementation 2 work correctly, we must add some kind of lock-mechanism; then it will be not only slower, but less elegant than implementaion 1.
Conclusion:
It is good to take MSB GC into the C++ standard as an optional feature.