C++: RAII

What is RAII?

RAII stands for “Resource Acquisition Is Initialization”. It is probably one of the nicest and most useful features that C++ has given to the world. D and Rust incorporated it as part of their specifications too.

What does it mean?

RAII, “obviously”, means that any entity that asks for a resource from the system (memory, file handle, network connection, etc.) should be responsible for releasing such a resource when its life has ended.

In C++ jargon, it means that any resource needed by an object must be acquired by the object’s constructor and released in its destructor.

Thanks to this very interesting feature, when a variable that represents an object created with value semantics goes out of scope, its destructor is invoked automatically and seamlessly, thus releasing any resource the object could have acquired in its lifetime.

That solves a lot of resource-related issues in a very transparent way when the variables go out of scope:

  • Any dynamically allocated memory owned by this object can be released.
  • Any file handle open can be closed.
  • Any network connection can be closed.
  • Any database connection can be closed.
  • Any Registry handled returned.
  • Any mutex unlocked
  • … and so on.

The nicest thing is, though several languages provide garbage collectors that are limited to handling memory, RAII is a cleaner alternative to handling NOT ONLY memory but any kind of resources.

Let’s see how we can use it.

First, let’s see how these constructor and destructor are invoked:

#include <iostream>

class A final
{
    int n;
public:
    explicit A(int n) : n{n} { std::cout << "Hello " << n << std::endl; }
    ~A() { std::cout << "Bye " << n << std::endl; }
};

void test()
{
    A a{1};
    A b{2};
    A c{3};
}

int main()
{
    std::cout << "Begin" << std::endl;
    test();
    std::cout << "End" << std::endl;
}

When running this, the output will be:

Begin
Hello 1
Hello 2
Hello 3
Bye 3
Bye 2
Bye 1
End

We can notice two things here:

  1. The destructors are invoked automatically before exiting the function test. Why there? Because a, b, and c were created in that code block.
  2. The destructor calling order is inverse to its creation order.

So, since the destructors are invoked automatically, we can use that interesting feature (RAII) to free any resource acquired by our code. For example, modifying the class A to store that int value in the heap instead (bad idea, by the way):

class A final
{
    int* pn;
public:
    explicit A(int n) 
    : pn{new int{n}} 
    {
        std::cout << "Hello " << *pn << std::endl; 
    }

    ~A()
    { 
        std::cout << "Bye " << *pn << std::endl; 
        delete pn;
    }
};

Notice that I am acquiring the resource (allocating memory) in the constructor and releasing it in the destructor.

In this way, the user of my class A does not need to worry about the resources it uses.

“Out of scope” also means that if my function ends abruptly or returns prematurely, the compiler will guarantee that the destructor of the objects will still be invoked before transferring the control to the caller.

Let’s test that by adding an exception:

#include <iostream>

class A final
{
    int* pn;
public:

    explicit A(int n) 
    : pn{new int{n}} 
    {
        std::cout << "Hello " << *pn << std::endl; 
    }

    ~A()
    { 
        std::cout << "Bye " << *pn << std::endl; 
        delete pn;
    }
};

void test(int nonzero)
{
    A a{1};
    A b{2};

    if (nonzero == 0)
        throw "Arg cannot be zero";

    A c{3};
}

int main()
{
    std::cout << "Begin" << std::endl;
    try
    {
        test(0);
    }
    catch (const char* e)
    {
        std::cout << e << std::endl;
    }
    std::cout << "End" << std::endl;
}

Notice that I am throwing an exception after objects a and b were created. When the exception occurs, the function test ends abruptly, but it will invoke the destructors of a and b before going to the catch block.

The destructor of object c was not invoked because the object was not created when the exception occurred.

The same behavior occurs if you return prematurely from a function.

Now, look at the class B that I have added to my example:

#include <iostream>

class A final
{
    int* pn;
public:
    explicit A(int n) 
    : pn{new int{n}} 
    {
        std::cout << "Hello " << *pn << std::endl; 
    }

    ~A()
    { 
        std::cout << "Bye " << *pn << std::endl; 
        delete pn;
    }
};

class B final
{
    A a;
    A b;
    
public:
    B(int valueA, int valueB) : a{valueA}, b{valueB} { }
};

void test()
{
    B a { 4, 5};
    B b { 6, 7};
}

int main()
{
    std::cout << "Begin" << std::endl;
    test();
    std::cout << "End" << std::endl;
}

The output is:

Begin
Hello 4
Hello 5
Hello 6
Hello 7
Bye 7
Bye 6
Bye 5
Bye 4
End

Why are the destructors of A being called when B objects go out of scope if I did not write a destructor for B?

Because when you do not write a destructor, the compiler generates one automatically that invokes the destructors of all member variables with value semantics.

So, if your basic classes handle resources explicitly, the likelihood of you needing to acquire or release resources explicitly in your constructors or destructors is actually low.

What about pointers?

RAII does not work with raw pointers, so if you declare something like:

int* array = new int[1024];

in a function, nothing will happen when that variable array goes out of scope.

Is there any way to have pointers handled by RAII?

YES! Through smart pointers!

Other non-memory related uses?

  • std::ifstream and std::ofstream close automatically the file they opened to be read or written.
  • std::lock_guard<T> locks a mutex in its constructor and unlocks it in its destructor, avoiding threads locked by mistake.
  • If you are writing some UI, you probably could need a MouseRestorer that would automatically set the mouse to its default value after being changed to an hourglass in a time-consuming piece of code
Schäfersee, Reinickendorf, Berlin

Amazon Music: https://music.amazon.de/albums/B0CSX3TR4M?marketplaceId=A1PA6795UKMFR9&musicTerritory=DE&ref=dm_sh_ku2wyU1opyQzXFxRLIU7O2Aux&trackAsin=B0CSX4QG1T

Apple Music: https://music.apple.com/us/album/after-the-winter-single/1726777022

Deezer: https://deezer.page.link/XEvJTwFmmkLoRvj4A

Spotify: https://open.spotify.com/track/2eTeor7GIn3hlNT8jbL9ZH?si=859e55953ea24231

YouTube: https://www.youtube.com/watch?v=RmscqH10NpY

YouTube Music: https://music.youtube.com/watch?v=RmscqH10NpY

New single: “After the winter”

C++ vs. Rust: Factorial

Let’s dig a little bit in some implementations (in C++ and Rust) of a function that computes the factorial of an integer passed as argument. I will try to make them as similar as possible and will expose the differences between both:

Recursive factorial

This is the simplest and most known factorial implementation:

int factorial(int n)
{
    if (n <= 1)
        return 1;

    return n * factorial(n - 1);
}

Now, the “same” implementation in Rust:

fn factorial(n : i32) -> i32
{
    if n <= 1
    {
        return n;
    }
        
    return n * factorial(n - 1);
}

Though similar and probably producing the same binaries, there are very interesting differences to take into account:

  1. All functions in Rust start with the “fn” keyword. In C++ they start with the function return type, void, or auto.
  2. In Rust you must specify the return type after ->. Since C++11 you can do the same if you mark your method as “auto“. If you do not specify the return type, the function does not return anything (like a C++ void function).
  3. The Rust type “i32” refers to a 32-bit integer. In C++ “int” represents an integer that could have (as far as I know, all current implementations have a 32-bit integer called: “int“) a 32-bit representation. This could be not true for old platforms, compilers or very small ones where the int could be 16-bit. Having an integer with well-defined size for all platforms make code portability easier. (C++ also have the int32_t alias, but is not an actual type).
  4. Rust’s “if” discourages the usage of parenthesis in the expression to evaluate.
  5. Rust mandates the “if” and “else” blocks will be enclosed with curly braces.

Non-recursive implementation

C++ version, using “while“. I am not using “for” because the C/C++/Java/C# -like “for” does not exist in Rust.

int nonRecursiveFactorial(int n)
{
    int r = 1;
    
    while (n >= 1)
    {
        r *= n;
        n--;
    }

    return r;
}

And now, the same code in Rust:

fn non_recursive_factorial(mut n : i32) -> i32
{
    let mut r = 1;
    
    while n >= 1
    {
        r *= n;
        n -= 1;
    }
    
    return r;
}

Again, interesting differences:

  1. I called “nonRecursiveFactorial” my function in C++ and “non_recursive_factorial” my function in Rust. Though I can call my functions whatever I want, the Rust compiler suggests me to use snake_case instead of camelCase.
  2. Notice I marked my argument as “mut” and my variable rmut” as well. “mut” stands for “mutable” and means that the value of that variable can be modified in its lifetime. All variables in Rust are immutable by default (similar to a C++ const variable) and that simple feature removes a lot of concurrency problems.
  3. Again, while does not have parenthesis in its expresion.
  4. Notice I am writing n -= 1; instead of n--; in Rust. Rust does not have “++” or “--” operators because their existence would make lifetime management complicated and the code with those operators can be hard to read in some scenarios.

I want to use “for” anyway

C++ version:

int factorialWithFor(int n)
{
    int r = 1;
    
    for (int i = 2; i < n + 1; i++)
        r *= i;

    return r;
}

Rust version:

fn factorial_with_for(n : i32) -> i32
{
    let mut r = 1;
    
    for i in 2..n + 1
    {
        r *= i;
    }
    
    return r;
}

Once more, interesting differences:

  1. The “for” loop in Rust is a range-based-for-loop, similar to the C++11 range-based-for-loop or C# foreach.
  2. The variable i inside the loop is mutable, it is declared and lives only in that block.
  3. After the “in” Rust keyword, I wrote “2..n+1“. That is the Rust way of creating a range of values between [2; n + 1[ (so the loop will run until n only).
  4. If I would want to have a countdown instead, I could write “(2..n + 1).rev()” instead, that would downcount from n to 2.

Until now, very nice language indeed.

C++17: Structured bindings

When accessing to an element of a given compound type, you probably want to get its internal fields in order to work with them.

When tuples were introduced (my post about tuples), the way of doing this was similar to this:

std::tuple<int, std::string, std::string> person { 20050316, "Isabel", "Pantoja" };
int birth_date = std::get<0>(person);
std::string& first_name = std::get<1>(person);
std::string& last_name = std::get<2>(person);

In this way, you were able to access any elements inside the tuple. Quite useful, but quite verbose as well.

So, std::tie could help us to make this code by far easier to read:

std::tuple<int, std::string, std::string> person { 20050316, "Isabel", "Pantoja" };

int birth_date;
std::string first_name;
std::string last_name;

std::tie(birth_date, first_name, last_name) = person;

The magic that std::tie does here is extracting all elements inside of the tuple and mapping them to the values passed as non-const-references to the std::tie function.

C++17 introduced “structured binding”, a far better and evident and elegant way of doing this without getting lost in what std::tie or std::get<N> do.

Structured binding, as its name suggests, binds a set of variables to its corresponding values inside a tuple. Actually these constructs are supported:

  • std::tuple<T...>
  • std::pair<T, U>
  • std::array<T, N> and stack-based old-style arrays
  • Structs!

How does it work?

The example above could be re-written like this:

std::tuple<int, std::string, std::string> person { 20050316, "Isabel", "Pantoja" };
auto& [birth_date, first_name, last_name] = person;

So, the compiler will “decompose” person in its “atomic” values and will bind the birth_date reference to the first value in person, the first_name to the second value and the last_name to the third one.

Notice that birth_date, first_name, and last_name are references because of auto&. If I would have used auto instead, they would have been actual values instead.

And you can do the same thing with arrays:

std::array<int, 4> values {{ 8, 5, 2, 9 }};
auto [v0, v1, v2, v3] = values;
std::cout << "Sum: " << (v0 + v1 + v2 + v3) << "\n";

int values2[] = { 5, 4, 3 };
auto [i0, i1, i2] = value2;
std::cout << i0 << "; " << i1 << "; " << i2 << "\n";

With std::pair:

auto pair = std::make_pair(19451019, "María Zambrana");
auto& [date, name] = pair;
std::cout << date << ": " << name << "\n";

Or even with structs!!!

struct Point
{
  int x;
  int y;
};

Point p { 10, 25 };
auto [x, y] = p;
std::cout << "(" << x << "; " << y << ")\n";

This feature makes iterating maps incredibly elegant.

Compare this pre-C++11 code:

for (std::map<std::string, std::string>::const_iterator it = translations.begin();
     it != translations.end();
     it++)
{
  std::cout << "English: " << it->first << "; Spanish: " << it->second << "\n";
}

Using C++17, it could have been written like this in C++17:

for (auto& [english, spanish] : translations)
{
  std::cout << "English: " << english << "; Spanish: " << spanish << "\n";
}

Amazing!

C++ vs. Rust: Hello World

This is my first program in Rust, obviously, a “Hello World“! :)

Two ways of creating it:

1. Everything manually

a. Need to create a file with .rs extension. In my case: HelloWorld.rs

b. Write the actual program in that file:

// Hello World in Rust

/* 
 * Same multiline comment like in C
 */

fn main()
{
  println!("Hello world");
}

c. Go to the command line and compile the file with the rustc compiler

rustc HelloWorld.rs -o HelloWorld

d. Execute the binary file

./HelloWorld
Hello world

2. Using cargo.

a. cargo is the Rust package manager that helps you managing dependencies and also is useful in the build process. You can use it to create your program and compile it. So, we can create a new “cargo package“:

cargo new HelloWorld

b. That creates a new “cargo package” called “HelloWorld“: cargo new creates a new “HelloWorld” directory, that contains a Cargo.toml descriptor file and a src directory that contains a main.rs skeleton file that already contains a “Hello World” project similar to the one I wrote above:

fn main() {
    println!("Hello, world!");
}

c. To compile the package, we can build it using cargo too:

cd HelloWorld
cargo build

d. If everything is ok, a new directory called target is created and inside it, directories for debug or release builds (cargo build --release). Going to the debug folder we can run the HelloWorld executable.

3. “Hello World” content

The comments are similar to the C-like languages: // for simple line and /* */ for multiline comments.

The “fn” keyword identifies a block as a Rust function. All functions in Rust have a name and a set of arguments. The return type will be deduced automatically by the compiler.

main“, as in C, is the program entry point and is the function that is executed when you invoke the program from the command line.

println!” is a Rust macro that prints a line of the text specified. A Rust macro is a piece of code able to generate code by itself (metaprogramming).

This is it for now. I will continue writing about Rust while learning it. Thanks for reading!

4. Comparison with C++

This is the most similar implementation of “Hello world” in C++:

#include "fmt/core.h"

int main()
{
  fmt::print("Hello world\n");
}

I used libfmt to print the "Hello world” text to make both implementations as similar as possible.

Notice that Rust does not need any #include stuff. Actually Rust lets you import libraries in a modern way (similar to Java imports or C++20 modules) but println! is a macro included in the standard library, imported by default.

Function main() is also the program entry point in Rust, but it does not return anything, in C++, it MUST return an int, that, if not explicitly mentioned, it will return 0.

New single: “To the core (microkernel mix)”

Amazon Music: https://music.amazon.com/albums/B0BT61D1D9

Apple Music: https://music.apple.com/us/album/to-the-core-microkernel-mix-single/1668544148

Deezer: https://deezer.page.link/CERrBCQWV5DKSXqc8

Spotify: https://open.spotify.com/track/7bu9cNwhcsQFVzckI0AjTd?si=80e9b6c0f0834729

YouTube: https://www.youtube.com/watch?v=HEhYw1lalNE

YouTube Music: https://music.youtube.com/watch?v=HEhYw1lalNE


This single is part of a larger project I am working on that also contains the “Preludes” I have already published.

Though this “microkernel mix” is a minimalistic and short version of the one contained in the forthcoming project, it captures completely the Andean essence and landscape I pretend to give to the theme.

Thanks for listening to it.

C++: boost::pfr

At work I used this library some days ago and I find it amazingly useful:

Basically, boost::pfr lets you work with the fields of a given struct, as a std::tuple, letting you access the elements through an index representing the position where the field is defined at inside the struct.

boost::pfr has also the benefit of being header-file-only and of not having any dependency with any other boost library, making it easy to install (copying its header files and that’s it) and use it.

Let’s see the example below. Suppose you have a struct Person:

struct Person
{
  std::string first_name;
  std::string last_name;
  int birth_year;
};

With boost::pfr, you can access any member in the struct given an index using a method called get() that is very similar to its std::tuple counterpart:

#include "boost/pfr.hpp"

int main()
{
  Person composer { "Martin", "Gore", 1961};
  
  auto& a = boost::pfr::get<0>(composer); // will return a std::string reference
  auto& b = boost::pfr::get<1>(composer);
  auto& c = boost::pfr::get<2>(composer); // will return a reference to the int field

  std::cout << a << ", " << b << ", " << c << "\n";
  return 0;
}

To get then number of elements in a struct, you have boost::pfr::tuple_size:

int main()
{
  std::cout << boost::pfr::tuple_size<Person>::value << "\n";  // returns 3 for our struct
}

To get the type of a given parameter, you have boost::pfr::tuple_element:

int main()
{
  boost::pfr::tuple_element<0, Person>::type s; 
  return 0;
}

In the example above, I declared a variable s whose type is the same type of the element in the 0-th position in the struct Person (i.e. a std::string).

Use cases:

You could create a generic library to iterate through all the members of any struct and do something with each member (kind of std::for_each [boost::pfr provides a for_each_field function template to do this iteration] or std::visit), for example, printing its values out (see my example below), saving them to disk, deserializing them or populating its values from a library (think of a SQL result set or a JSON object).

On printing a struct values out, boost::pfr already ships with a method called io_fields that does exactly that:

int main()
{
  Person singer { "Dave", "Gahan", 1962 };
  std::cout << boost::pfr::io_fields(singer) << "\n";
}

This prints out “{ Dave, Gahan, 1962 }“.

boost::pfr also ships with a lot of utilities to compare elements from a struct in other or to use any struct as a key on standard library maps and sets.

To learn more about this nice library, visit its documentation: https://apolukhin.github.io/pfr_non_boost/

C++17: std::string_view

C++17 shipped with a very useful non-owning read-only string handling class template: std::basic_string_view<CharT, CharTraits> with several instantiations mirroring the std::basic_string class template: std::string_view, std::wstring_view, std::u8string_view, std::u16string_view, and std::u32string_view.

A std::string_view instance contains only a pointer to the first character in a char array and the length of the string. The std::string_view does not own such array and thus, it is not responsible for the lifetime of the text it refers to.

Since it contains the length of the string it represents, the string does not need to end with a '\0' character. This feature (the non-‘\0’ terminated string) enables a lot of interesting features like creating substring views by far faster than its std::string counterpart (since creating a substring means just updating the pointer and the length of the new std::string_view instance).

How a std::string_view is instantiated?

std::string_view today = "Monday";  // string_view constructed from a const char*
std::string aux = "Tuesday";
std::string_view tomorrow = aux;  // string_view constructed from a std::string
std::string_view day_after_tomorrow = "Wednesday"sv;  // string_view constructed from a std::string_view
constexpr std::string_view day_before_friday = "Thursday"; // compile-time string_view

How can I use a std::string_view?

A lot of classes from the C++ standard library have been updated to use the std::string_view as a first class citizen, so, for example, to print out a std::string_view instance, you could simply use the std::cout as usual:

std::string_view month = "September";
std::cout << "This month is " << month << "\n";

As I mentioned earlier, you can use the std::string_view to execute several actions in the underlying text with a better performance, for example, to create substrings:

#include <string_view>
#include <iostream>

int main()
{

    std::string_view fullName = "García Márquez, Gabriel";

    // I need to separate first name and last name

    // I find the index of the ","
    auto pos = fullName.find(",");
    if (pos == std::string_view::npos) // NOT FOUND
    {
        std::cerr << "Malformed full name\n";
        return -1;
    }

    std::string_view lastName = fullName.substr(0, pos);
    std::string_view firstName = fullName.substr(pos + 2);

    std::cout << "FIRST NAME: " << firstName;
    std::cout << "\nLAST NAME:  " << lastName << "\n";

    return 0;
}

To verify if a text starts or ends with something (starts_with() and ends_with() were introduced in C++20):

std::string_view price = "125$";
if (price.endsWith("$"))
{
    price.remove_suffix(1); // removes 1 char at the end of the string_view
    std::cout << price << " dollar\n";
}

It exposes a lot of functionality similar to the std::string class, so its usage is almost the same.

How can I get the content of a std::string_view?

  • If you want to iterate the elements, you can use operator[], at() or iterators in the same way that you do it in strings.
  • If you want to get the underlying char array, you can access to it through the data() method. Be aware the underlying char array can miss the null character as mentioned above.
  • If you want to get a valid std::string from a std::string_view, there is no automatic conversion from one to other, so you need to use a explicit std::string constructor:
std::string_view msg = "This will be a string";
std::string msg_as_string { msg };

std::cout << msg_as_string << "\n";

Handle with care

And though probably you are already imagining the scenarios a string_view can be used into your system, take into account that it could bring some problems because of its non-owning nature, for example this code:

std::string_view say_hi()
{
  std::string_view hi = "Guten Tag";
  return hi;
}

Is a completely valid and correct usage of a std::string_view.

But this slightly different version:

std::string_view say_hi()
{
  std::string_view hi = "Guten Tag"s;
  return hi;
}

Returns a corrupt string and the behavior for this is undefined. Notice the “s” at the end of the literal. That means “Guten Tag” will be a std::string and not a const char*. Being a std::string means a local instance will be created in that function and the std::string_view refers to the underlying char array in that instance. BUT, since it is a local instance, it will be destroyed when it goes out of scope, destroying the char array and returning a dangling pointer inside the std::string_view.

Sutile, but probably hard to find and debug.

To read more about std::string_view, consult the ultimate reference:

https://en.cppreference.com/w/cpp/string/basic_string_view

New EP: “Dandelions”

Amazon Music: https://www.amazon.de/music/player/albums/B0B3MBQ1KV

Apple Music: https://music.apple.com/us/album/dandelions-ep/1629980374

Claro Música: https://www.claromusica.com/album/27806174/MX

Deezer: https://deezer.page.link/RvRNZcBy7abDLAqF6

Spotify: https://open.spotify.com/album/5QXKrdbz0nWM5an7bob1qz?si=o5eTZBO5Tw-W4ZENccSZ6Q

YouTube Music: https://music.youtube.com/playlist?list=OLAK5uy_lk_kmNv8ihX5TfIU7pm9km27PsuvelxwI


Software used:

  • FL Studio 20
  • OpenMPT 1.30
  • Reaktor 5
  • Kontakt 6.7
  • Audacity 2.2.2

Thanks for listen to it!


I wrote these songs between 1997 and 2002 using Impulse Tracker and ModPlug Tracker (the actual ancestor of OpenMPT, the tracker I used to release this EP).

Three friends of mine (Miguel Colque, Eloy Espozo and Rubén Bobarín) helped me to mix and record the first version of “Un eco en el silencio” (“Echo in Silence”) using my Yamaha PSR-19 and Miguel’s Casio keyboard. Since we used a 4-track audio recorder, I had to save one sound on top of other and, because of that, the resulting song sound quality was not so nice. I actually made several mistakes playing while recording, so the result was far from a “release to manufacturing” quality.

For the current version of Echo in Silence, I used several sampled sounds of that Yamaha PSR-19 (samples I recorded when I still owned it) and also used several Kontakt and Reaktor instruments. I sequenced all instruments in OpenMPT. So, the version in Dandelions sounds pretty similar (but by far cleaner) to the original one recorded with friends 25 years ago!! :)

Echo in Silence (Z80 mix) is a pop-synthish version of Echo in Silence, with faster tempo and 80’s sounds.

C++14: [[deprecated]]

[[deprecated]] is another attribute that is useful to mark something (a function, a method, a variable, a class, etc.) as still valid, but that has been superseded by other newer stuff and that probably will be removed in the future.

In a similar vein to [[nodiscard]], [[deprecated]] can return a message explaining why this entity has been marked as such.

The compiler will show a warning when a deprecated entity is being actually used in our code.

For example, I have this code:

#include <iostream>

void print(const std::string& msg)
{
    std::cout << msg << "\n";
}

int main()
{
    print("Hello world");
}

After that a lot of functions and code started to use my print() function, I realize that a newer version with std::string_view instead of std::string could have better performance and, since I do not want to break any code, I consider having both functions in my system.

So, to discourage the usage of my old function, I mark it as deprecated:

#include <iostream>


void println(std::string_view msg)
{
    std::cout << msg << "\n";
}

[[deprecated("Use println instead")]]
void print(const std::string& msg)
{
    std::cout << msg << "\n";
}

int main()
{
    print("Hello world");
}

But, since I am still using the old version in my main() function, the compiler will return a warning like this one:

main.cpp:17:24: warning: ‘void print(const string&)’ is deprecated: Use println instead [-Wdeprecated-declarations]

That will dissappear when I will replace all the invocation to print() with println().

C++17: [[nodiscard]] attribute

C++17 adds a new attribute called [[nodiscard]] to let the user know that a return value from a function or method should be handled properly or assigned to a value.

For example, look to this code:

int sum(int a, int b)
{
  return a + b;
}

int main()
{
  sum(10, 20);
  return 0;
}

It produces no result or side-effects, but if the programmer forgot assigning the return value to a variable by mistake, the error will not be immediately obvious.

Now, in this scenario:

char* getNewMessage()
{
  char* nm = new char[100];
  strcpy(nm, "Hello world");
  return nm;
}

int main()
{
  getNewMessage();
  return 0;
}

There is a memory leak produced because the returned value was not stored anywhere and there is no way to deallocate its memory.

Marking a function or method with [[nodiscard]], encourages the compiler to show a compilation warning when it is invoked and its return value is simply bypassed.

You can also write an additional message with the [[nodiscard]] attribute. That message will be displayed if a warning is generated.

In my examples, we could mark my functions like this:

#include <cstring>

[[nodiscard]]
int sum(int a, int b)
{
  return a + b;
}

[[nodiscard("Release the memory using delete[]")]]
char* getNewMessage()
{
  char* nm = new char[100];
  strcpy(nm, "Hello world");
  return nm;
}

int main()
{
  sum(10, 20);
  getNewMessage();
  return 0;
}

And in this case, g++ returns the following compilation warnings:

In function 'int main()':
<source>:19:6: warning: ignoring return value of 'int sum(int, int)', declared with attribute 'nodiscard' [-Wunused-result]

<source>:20:16: warning: ignoring return value of 'char* getNewMessage()', declared with attribute 'nodiscard': 'Release the memory using delete[]' [-Wunused-result]

Though using it could add a lot of verbosity to your method declarations, it is a good idea using it because it prevents some errors to occur.

More on [[nodiscard]]: https://en.cppreference.com/w/cpp/language/attributes

C++20: Useful concepts: Requiring type T to be derived from a base class

How can I create a concept that requires my parameterized types to inherit from a base class?

I am creating a heavily object-oriented class hierarchy and I want the functions related to that class hierarchy to accept only instances of classes derived from the base class of that hierarchy.

So, for example, I have this base class:

class Object
{
public:
    virtual ~Object() = default;

    virtual std::string to_string() const = 0;
};

I create derived classes from such class, for example: class Int.

class Int : public Object
{
    int n;
public:
    Int(int n) : n{n}  {}

    std::string to_string() const override
    {
        return std::to_string(n);
    }
};

And now I want to create a function template “print” that invokes the method “to_string()” of the given parameter and prints it out.

Because of my design, I want my function template to accept only instances of classes derived from my class Object.

In this case, I can create a C++20 concept using the type trait std::is_base_of<Base, Derived>, like this:

#include <type_traits>

template <typename T>
concept ConceptObject = std::is_base_of<Object, T>::value;

In the lines above, I am creating a new C++20 concept called “ConceptObject” that will require my type T fulfill the requirement of T being a derived class from Object.

So, finally, my function template “print” can be expressed in this way:

template <ConceptObject T>
void print(const T& s)
{
    std::cout << s.to_string() << "\n";
}

And it will only compile if the parameter s is an instance of a class derived from Object:

int main()
{
    print(Int{5});
}

Pretty nice!

If you want to read more about C++ concepts, I have this post introducing them: C++20: Concepts, an introduction

C++20: {fmt} and std::format

In this post I will show a very nice open source library that lets the programmers create formatted text in a very simple, type-safe and translatable way: {fmt}

{fmt} is also the implementation of reference for the C++20 standard std::format (the {fmt}‘s author [https://www.zverovich.net/] submitted his paper to the standard committee) but until this moment (June, 2021) only Microsoft Visual Studio implements it. So I will describe the standalone library for now.

These are the main features we can find in {fmt}:

  • We can specify the format and the variables to be formatted, similar to C printf family.
  • The {fmt} functions do not require the programmer to match the type of the format specifier to the actual values the are being formatted.
  • With {fmt}, programmers can optionally specify the order of values to be formatted. This feature is very very useful when internationalizing texts where the order of the parameters is not always the same as in the original language.
  • Some format validations can be done in compile time.
  • It is based on variadic templates but there are lower-level functions on this library that fail over to C varargs.
  • Its performance its way ahead to C++ std::ostream family.

To test {fmt}, I used Godbolt’s Compiler Explorer.

Hello world

This is a very simple “Hello world” program using {fmt}:

#include <fmt/core.h>

int main()
{
    fmt::print("Hello world using {{fmt}}\n");
}

fmt::print() is a helper function that prints formatted text using the standard output (similar to what std::cout does).

As you can see, I did not specify any variables to be formatted BUT I wrote {{fmt}} instead of {fmt} because {{ and }} are, for the {fmt} functions, escape sequences for { and } respectively, which when used as individual characters, contain a format specifier, an order sequence, or simply mean that will be replaced by a parameterized value.

Using simple variable replacements

For example I want to print out two values, I can do something like:

int age = 16;
std::string name = "Ariana";

fmt::print("Hello, my name is {} and I'm {} years old", name, age);

This will print:

Hello, my name is Ariana and I'm 16 years old.

fmt::print() replaced the {} with the respective variable values. Notice also that I used std::string and it worked seamlessly. Using printf(), the programmers should get the const char* representation of the string to be displayed.

If the programmers specify less variables than {}, the compiler (or runtime) returns an error. More on this below.

If the programmers specify more variables than {}, the extra ones are simply ignored by fmt::print() or fmt::format().

Defining arguments order

The programmers can also specify the order the parameters will be replaced:

void show_numbers_name(bool ascending)
{
    std::string_view format_spec = ascending ? "{0}, {1}, {2}\n" : "{2}, {1}, {0}\n";
    
    auto one = "one";
    auto two = "two";
    auto three = "three";

    fmt::print(format_spec, one, two, three);
}

int main()
{
    show_numbers_name(true);
    show_numbers_name(false);
}

As you can see, the {} can contain a number that tells {fmt} the number of the argument that will be used in such position when formatting the output.

Formatting containers

Containers can easily printed out including #include <fmt/ranges.h>

std::vector<int> my_vec = { 10, 20, 30, 40, 50 };
fmt::print("{}\n", my_vec);

Format errors

There are two ways that {fmt} uses to process errors:

If there is an error in the format, a runtime exception is thrown, for example:

int main()
{
    try
    {
        fmt::print("{}, {}, {}\n", 1, 2);
    }
    catch (const fmt::format_error& ex)
    {
        fmt::print("Exception: {}\n", ex.what());
    }
}

In the example above, I say that I have three parameters but only provided two variables, so a fmt::format_error exception is thrown.

But if the format specifier is always constant, we can specify the format correctness in runtime in this way:

#include <fmt/core.h>
#include <fmt/compile.h>

int main()
{
    fmt::print(FMT_COMPILE("{}, {}, {}\n"), 1, 2);
}

FMT_COMPILE is a macro found in <fmt/compile.h> that performs the format validation in compile-time, thus in this case, a compile-time error is produced.

Custom types

To format your custom types, you must to create a template specialization of the class template fmt::formatter and implement the methods parse() and format(), as in this example:

// My custom type
struct person
{
    std::string first_name;
    std::string last_name;
    size_t social_id;
};

// fmt::formatter full template specialization
template <>
struct fmt::formatter<person>
{
    // Parses the format specifier, if needed (in my case, only return an iterator to the context)
    constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }

    // Actual formatting. The second parameter is the format specifier and the next parameters are the actual values from my custom type
    template <typename FormatContext>
    auto format(const person& p, FormatContext& ctx) {
        return format_to(
            ctx.out(), 
            "[{}] {}, {}", p.social_id, p.last_name, p.first_name);
    }
};

int main()
{
    fmt::print("User: {}\n", person { "Juana", "Azurduy", 23423421 });
}

Neat, huh?

Links

{fmt} GitHub page: https://github.com/fmtlib/fmt

{fmt} API reference: https://fmt.dev/latest/api.html

Compiler explorer: https://godbolt.org/

C++17: std::optional

The C++17 standard library ships with a very interesting class template: std::optional<T>.

The idea behind it is to make explicit the fact that a variable can hold or not an actual value.

Before the existence of std::optional<T>, the only way to implement such semantics was through pointers or tagged unions (read about C++17 std::variant here).

For example, if I want to declare a struct person that stores a person’s first name, last name and nickname; and since not all people have or not a nickname, I would have to implement that (in older C++) in this way:

struct person
{
  std::string first_name;
  std::string last_name;
  std::string* nickname; //no nickname if null
};

To make explicit that the nickname will be optional, I need to write a comment stating that “null” represents “no nickname” in this scenario.

And it works, but:

  • It is error prone because the user can easily do something like: p.nickname->length(); and run into an unexpected behavior when the nickname is null.
  • Since the nickname will be stored as a pointer, the instance needs to be created in heap, adding one indirection level and one additional dynamic allocation/deallocation only to support the desired behavior (or the programmers need to have the nickname manually handled by them and set a pointer to that nickname into this struct).
  • Because of the last reason, it is not at all obvious if the instance pointed to by said pointer should be explicitly released by the programmer or it will be released automatically by the struct itself.
  • The “optionalness” here is not explicit at all at code level.

std::optional<T> provides safeties for all these things:

  • Its instances can be created at stack level, so there will not be extra allocation, deallocation or null-references: RAII will take care of them (though this depends on the actual Standard Library implementation).
  • The “optionalness” of the attribute is completely explicit when used: Nothing is more explicit than marking as “optional” to something… optional, isn’t it?
  • Instances of std::optional<T> hide the direct access to the object, so to access its actual value they force the programmer to do extra checks.
  • If we try to get the actual value of an instance that is not storing anything, a known exception is thrown instead of unexpected behavior.

Refactoring my code, it will look like this one:

#include <optional>
#include <string>

struct person
{
  std::string first_name;
  std::string last_name;
  std::optional<std::string> nickname;
};

The code is pretty explicit and no need to further explanation or documentation about the optional character of “nickname”.

So let’s create two people, one with nickname and the other one with no nickname:

int main()
{
  person p1 { "John", Doe", std::nullopt };
  person p2 { "Robert", "Balboa", "Rocky" };
}

In the first instance, I have used “std::nullopt” which represents an std::optional<T> instance with no value (i.e. : an “absence of value”).

In the second case, I am implicitly invoking to the std::optional<T> constructor that receives an actual value.

The verbose alternative would be:

int main()
{
    person p1 { "John", "Doe", std::optional<std::string> { } };
    person p2 { "Robert", "Balboa", std::optional<std::string> {"Rocky"} };
}

The parameterless constructor represents an absence of value (std::nullopt) and the other constructor represents an instance storing an actual value.

Next I will overload the operator<< to work with my struct person, keeping in mind that if the person has a nickname, I want to print it out.

This could be a valid implementation:

std::ostream& operator<<(std::ostream& os, const person& p)
{
    os << p.last_name << ", " << p.first_name;
    
    if (p.nickname.has_value())
    {
        os << " (" << p.nickname.value() << ")";
    }
    
    return os;
}

The has_value() method returns true if the optional<T> instance is storing an actual value. The value can be retrieved using the value() method.

There is an overload for the operator bool that does the same thing that the has_value() method does: Verifying if the instance stores an actual value or not.

Also there are overloads for operator* and operator-> to access the actual values.

So, a less verbose implementation of my operator<< shown above would be:

std::ostream& operator<<(std::ostream& os, const person& p)
{
    os << p.last_name << ", " << p.first_name;
    
    if (p.nickname)
    {
        os << " (" << *(p.nickname) << ")";
    }
    
    return os;
}

Other way to retrieve the stored value, OR return an alternative value would be using the method “value_or()” method.

void print_nickname(const person& p)
{
    std::cout << p.first_name << " " << p.last_name << "'s nickname: "
              << p.nickname.value_or("[no nickname]") << "\n";
}

For this example, if the nickname variable stores an actual value, it will return it, otherwise, the value returned will be, as I coded: “[no nickname]”.

What will happen if I try to access to the optional<T>::value() when no value is actually stored? A std::bad_optional_access exception will be thrown:

try
{
    std::optional<int> op {};
    std::cout << op.value() << "\n";
}
catch (const std::bad_optional_access& e)
{
    std::cerr << e.what() << "\n";
}

Notice I have used the value() method instead of operator*. When I use operator* instead of value(), the exception is not thrown and the user runs into an unexpected behavior.

So, use std::optional<T> in these scenarios:

  • You have some attributes or function arguments that may have no value and are, therefore, optional. std::optional<T> makes that decision explicit at the code level.
  • You have functions that may OR may not return something. For example, what will be the minimum integer found in an empty list of ints? So instead of returning an int with its minimum value (std::numeric_limits<int>::min()), it would be more accurate to return an std::optional<int>.

Note that std::optional<T> does not support reference types (i.e. std::optional<T&>) so if you want to store an optional reference, probably you want to use a std::reference_wrapper<T> instead of type T (i.e. std::optional<std::reference_wrapper<T>>).

C++17: std::any

When trying to implement something that will store a value of an unknown data type (to be as generic as possible, for example), we had these possibilities before C++17:

  • Having a void* pointer to something that will be assigned at runtime. The problem with this approach is that it leaves all responsibility for managing the lifetime of the data pointed to by this void pointer to the programmer. Very error prone.
  • Having a union with a limited set of data types available. We can use still use this approach using C++17 variant.
  • Having a base class (e.g. Object) and store pointers to instances derived of that class (à la Java).
  • Having an instance of template typename T (for example). Nice approach, but to make it useful and generic, we need to propagate the typename T throughout the generic code that will use ours. Probably verbose.

So, let’s welcome to std::any.

std::any, as you already guess it, is a class shipped in C++17 and implemented in header <any> that can store a value of any type, so, these lines are completely valid:

std::any a = 123;
std::any b = "Hello";
std::any c = std::vector<int>{10, 20, 30};

Obviously, this is C++ and you as user need to know the data type of what you stored in an instance of std::any, so, to retrieve the stored value you have to use std::any_cast<T> as in this code:

#include <any>
#include <iostream>

int main()
{
    std::any number = 150;
    std::cout << std::any_cast<int>(number) << "\n";
}   

If you try to cast the value stored in an instance of std::any to anything but the actual type, a std::bad_any_cast exception is thrown. For example, if you try to cast that number to a string, you will get this runtime error:

terminate called after throwing an instance of 'std::bad_any_cast'
  what():  bad any_cast

If the value stored in an instance of std::any is an instance of a class or struct, the compiler will ensure that the destructor for that value will be invoked when the instance of std::any goes of scope.

Another really nice thing about std::any is that you can replace the existing value stored in an instance of it, with another value of any other type, for example:

std::any content = 125;
std::cout << std::any_cast<int>(content) << "\n";

content = std::string{"Hello world"};
std::cout << std::any_cast<std::string>(content) << "\n";

About lifetimes

Let’s consider this class:

struct A
{
  int n;
  A(int n) : n{n} { std::cout << "Constructor\n"; }
  ~A() { std::cout << "Destructor\n"; }
  A(A&& a) : n{a.n} { std::cout << "Move constructor\n"; }
  A(const A& a) : n{a.n} { std::cout << "Copy constructor\n"; }
  void print() const { std::cout << n << "\n"; }
};

This class stores an int, and prints it out with “print”. I wrote constructor, copy constructor, move constructor and destructor with logs telling me when the object will be created, copied, moved or destroyed.

So, let’s create a std::any instance with an instance of this class:

std::any some = A{4516};

This will be the output of such code:

Constructor
Move constructor
Destructor
Destructor

Why two constructors and two destructors are invoked if I only created one instance?

Because the instance of std::any will store a copy (ok, in this case a “moved version”) of the original object I created, and while in my example it may be trivial, in a complex object it cannot be.

How to avoid this problem?

Using std::make_any.

std::make_any is very similar to std::make_shared in the way it will take care of creating the object instead of copying/moving ours. The parameters passed to std::make_any are the ones you would pass to the object’s constructor.

So, I can modify my code to this:

auto some = std::make_any<A>(4517);

And the output will be:

Constructor
Destructor

Now, I want to invoke to the method “print”:

auto some = std::make_any<A>(4517);
std::any_cast<A>(some).print();

And when I do that, the output is:

Constructor
Copy constructor
4517
Destructor
Destructor

Why such extra copy was created?

Because std::any_cast<A> returns a copy of the given object. If I want to avoid a copy and use a reference, I need to explicit a reference in std::any_cast, something like:

auto some = std::make_any<A>(4517);
std::any_cast<A&>(some).print();

And the output will be:

Constructor
4517
Destructor

It is also possible to use std::any_cast<T> passing a pointer to an instance of std::any instead of a reference.

In such case, if the cast is possible, will return a valid pointer to a T* object, otherwise it will return a nullptr. For example:

auto some = std::make_any(4517);
std::any_cast<A>(&some)->print();
std::cout << std::any_cast<int>(&some) << "\n";

In this case, notice that I am passing a pointer to “some” instead of a reference. When this occurs, the implementation returns a pointer to the target type if the stored object is of the same data type (as in the second line) or a null pointer if not (as in the third line, where I am trying to cast my object from type A to int). Using this version overloaded version with pointers avoids throwing an exception and allows you to check if the returned pointer is null.

std::any is a very good tool for storing things that we, as implementers of something reusable, do not know a priori; it could be used to store, for example, additional parameters passed to threads, objects of any type stored as extra information in UI widgets (similar to the Tag property in Windows.Forms.Control in .NET, for example), etc.

Performance wise, std::any needs to store stuff in the heap (this assert is not completely correct: Where the stuff is actually stored depends on the actual library implementation and some of them [gcc’s standard library] store locally elements whose sizeof is small [thanks TheFlameFire]) and also needs to do some extra verification to return the values only if the cast is valid, so, it is not as fast as having a generic object known at compile time.

C++20: Concepts, an introduction

I am pretty new doing C++ Concepts, so I will post here the things I will learn while starting to use them.

C++ Concepts are one of these three large features that are shipped with C++20:

  • Concepts
  • Ranges
  • Modules

Basically, C++ Concepts define a set of conditions or constraints that a data type must fulfill in order to be used as a template argument.

For example, I would want to create a function that sums two values and prints the result. In C++17 and older I would code something like this:

template <typename A, typename B>
void sum_and_print(const A& a, const B& b)
{
    std::cout << (a + b) << "\n";
}

And it works properly for types A and B that DO have the operator+ available. If the types I am using do not have operator+, the compiler naïvely will try to substitute types A and B for the actual types and when trying to use the missing operator on them, it will fail miserably.

The way the compiler works is correct, but failing while doing the actual substitution with no earlier verification is kind of a reactive behavior instead of a proactive one. And in this way, the error messages because of substitution error occurrences are pretty large, hard to read and understand.

C++20 Concepts provide a mechanism to explicit the requirements that, in my example, types A and B would need to implement in order to be allowed to use the “sum_and_print” function template. So when available, the compiler will check that those requirements are fulfilled BEFORE starting the actual substitution.

So, let’s start with the obvious one: I will code a concept that mandates that all types that will honor it will have operator+ implemented. It is defined in this way:

template <typename T, typename U = T>
concept Sumable =
 requires(T a, U b)
 {
    { a + b };
    { b + a };
 };

The new keyword concept is used to define a C++ Concept. It is defined as a template because the concept will be evaluated against the type or types that are used as template arguments here (in my case, T and U).

I named my concept “Sumable” and after the “=” sign, the compiler expects a predicate that needs to be evaluated on compile time. For example, if I would want to create a concept to restrict the types to be only “int” or “double”, I could define it as:

template <typename T>
concept SumableOnlyForIntsAndDoubles = std::is_same<T, int>::value || std::is_same<T. double>::value;

The type trait “std::is_same<T, U>” can be used here to create the constraint.

Back to my first example, I need that operator+ will be implemented in types A and B, so I need to specify a set of requirements for that constraint. The new keyword “requires” is used for that purpose.

So, any definition between braces in the requires block (actually “requires” is always a block, even when only a requirement is specified) is something the types being evaluated must fulfill. In my case, “a+b” and “b+a” must be valid operations. If types T or U do not implement operator+, the requirements will not be fulfilled and thus, the compiler will stop before even trying to substitute A and B for actual types.

So, with such implementation, my function “sum_and_print” works like a charm for ints, doubles, floats and strings!

But, what if I have another type like this one:

struct N
{
    int value;

    N operator+(const N& n) const
    {
        return { value + n.value };
    }
};

Though it implements operator+, it does not implement operator<< needed to work with std::cout.

To add such constraint, I need to add an extra requirement to my concept. So, it could be like this one:

template <typename T, typename U = T>
concept Sumable =
 requires(T a, U b)
 {
    { a + b };
    { b + a };
 }
 && requires(std::ostream& os, const T& a)
 {
     { os << a };
 };

The operator && is used here to specify that those requirements need to be fulfilled: Having operator+ AND being able to do “os << a“.

If my types do not fulfill such requirements, I get an error like this in gcc:

<source>:16:5:   in requirements with 'std::ostream& os', 'const T& a' [with T = N]
<source>:18:11: note: the required expression '(os << a)' is invalid
   18 |      { os << a };
      |        ~~~^~~~

That, though looks complicated, is far easier to read than the messages that the compiler produces when type substitution errors occur.

So, if I want to have my code working properly, I need to add an operator<< overloaded for my type N, having finally something like this:

#include <iostream>

template <typename T, typename U = T>
concept Sumable =
 requires(T a, U b)
 {
    { a + b };
    { b + a };
 }
 && requires(std::ostream& os, const T& a)
 {
     { os << a };
 };

template <Sumable A, Sumable B>
void sum_and_print(const A& a, const B& b)
{
    std::cout << (a + b) << "\n";
}

struct N
{
    int value;

    N operator+(const N& n) const
    {
        return { value + n.value };
    }
};

std::ostream& operator<<(std::ostream& os, const N& n)
{
    os << n.value;
    return os;
}

int main()
{
    sum_and_print( N{6}, N{7});
}

Notice that in my “sum_and_print” function template I am writing “template <Sumable a, Sumable b>” instead of the former “template <typename A, typename B>“. This is the way I ask the compiler to validate such type arguments against the “Sumable” concept.


What if I would want to have several “greeters” implemented in several languages and a function “greet” that will use my greeter to say “hi”. Something like this:

template <Greeter G>
void greet(G greeter)
{
    greeter.say_hi();
}

As you can see, I want my greeters to have a method “say_hi“. Thus, the concept could be defined like this one in order to mandate the type G to have the method say_hi() implemented:

template <typename G>
concept Greeter = requires(G g)
{
    { g.say_hi() } -> std::convertible_to<void>;
};

With such concept in place, my implementation would be like this one:

template <typename G>
concept Greeter = requires(G g)
{
    { g.say_hi() } -> std::convertible_to<void>;
};

struct spanish_greeter
{
    void say_hi() { std::cout << "Hola amigos\n"; }
};

struct english_greeter
{
    void say_hi() { std::cout << "Hello my friends\n"; }
};


template <Greeter G>
void greet(G greeter)
{
    greeter.say_hi();
}


int main()
{
    greet(spanish_greeter{});
    greet(english_greeter{});
}

Why would I want to use concepts instead of, say, base classes? Because:

  1. While using concepts, you do not need to use base classes, inheritance, virtual and pure virtual methods and all that OO stuff only to fulfill a contract on probably unrelated stuff, you simply need to fulfill the requirements the concept defines and that’s it (Interface Segregation of SOLID principles would work nice here, anyway, where your concepts define the minimum needed possible constraints for your types).
  2. Concepts are a “Zero-cost abstraction” because their validation is performed completely at compile-time, and, if properly verified and accepted, the compiler does not generate any code related to this verification, contrary to the runtime overhead needed to run virtual things in an object-oriented approach. This means: Smaller binaries, smaller memory print and better performance!

I tested this stuff using gcc 10.2 and it works like a charm.

Deleaker, part 0: Intro

I am testing this nice desktop tool called “Softanics Deleaker” (https://www.deleaker.com/). It was written by Artem Razin and, as you can deduce by its name, it is an application that helps the programmers to find memory leaks on C++, Delphi and .NET applications.

Starting this post, I will post several blog entries about my experiences using it and the features it exposes.

I installed it and installed the Visual Studio extension that ships with the installer. For my tests, I am using Visual Studio 2019 16.4 preview.

In Visual Studio I created a C++ console application and wrote this very simple and correct application:

int main()
{
    std::cout << "Hello World!\n";
    return 0;
}

When I run the local debugger, and since I have installed the Deleaker VS extension, the leaker will load all libraries and symbols of my application and will open a window similar to this one:

I still do not know what all those options mean, but the important thing here is the “No leaks found” message. The filter containing the “266 hidden” items refers to known leaks that Deleaker knows that exist in the Microsoft C Runtime Library.

Now, I will create a very small program too containing a small memory leak:

int main()
{
    for (int i = 0; i < 10; i++)
    {
        char* s = new char{'a'};
        std::cout << *s << "\n";
    }

    return 0;
}

As obviously observed, I am allocating dynamically one byte to contain a character and I am forgetting to delete it. When I debug it, I get this interesting Deleaker window:

Now Deleaker detected my forgotten allocation and says that to me: “ConsoleApplication2.exe!main Line 7”.

As you can see, the “Hit Count” says that the allocation occurred 10 times (because my loop) and it says that 370 bytes leaked on this problem. Though that seems weird because I allocated only 1 byte 10 times, the 370 bytes appear because I compiled my code in Debug Mode and the compiler adds a lot of extra info per allocation. When I changed my compilation to Release Mode, I got the actual 10 bytes in the Size column.

When you click into the information table in the row containing the memory leak information, the Visual Studio editor highlights that line and moves the caret to such position (the new char{‘a’} line , so you realize where you allocated memory that was not released.

And that is it for now.

In next blog entries I will explore how to “Deleak” not so obvious things, how Deleaker behaves with shared pointers, COM objects, shared libraries, templates, virtual destructors and so on :)

Happy 2020!