The C language
The C language was co-developed with UNIX and played and important part in the ICT history. It was a small language with little overhead. Unfortunately in the use of it it had some issues as well:
- dangling pointers
- memory leaks
- buffer overruns
C++
C++ original goal was to offer and object oriented programming language compatible with C. Later it incorporated generics as well in the form of 'templates'.
Modern C++ offers solutions for above issues:
-
smart pointers like unique_ptr and shared_ptr own a memory resource. The
smart pointer releases the memory when the last reference to the smart
pointer is going out of scope. This solves the problems of dangling pointers
and memory leaks. Note that shared_ptr's are not completely opaque: they
still have some sharp edges as well like the circular reference problem and the inability to used shared_from_this from a constructor
-
std::vector offers a safe way to manage a contiguous buffer. It has
iterators for access and it automatically grows when elements are added. The
memory is released when going out of scope. Again it offers an alternative
for all problems above.
- std::string is comparable with std::vector but is specialized for strings. C uses character arrays and they are prone for all of the above mentioned problems
Good C++ code can be as fast or even faster than corresponding C code. As
usual one has to know the idioms and read the standard C++ books.
Example
Suppose you have a function which fills a variable length buffer and do some processing on it. It has multiple early out paths.
C case
In C this could be:
#include <stdlib.h>
bool f()
{
size_t nLen = GetBufferLength();
int* p = malloc(nLen * sizeof(int));
if (!GetBuffer(p, nLen))
{
free(p);
return false;
}
if (!EncodeBuffer(p, nLen))
{
free(p);
return false;
}
free(p);
return true;
}
C++ case
In C++ one can use std:vector
as variable length buffer:
#include <vector>
bool f()
{
const size_t nLen = GetBufferLength();
std::vector<int> vec(nLen);
if (!GetBuffer(vec.data(), vec.size()))
{
return false;
}
if (!EncodeBuffer(vec.data(), vec.size()))
{
return false;
}
return true;
}
There is only one small performance drawback in using std::vector
: its
elements get
default
or
zero
initialized which may be an issue in case a huge buffer is allocated.
No comments:
Post a Comment