Heap allocations in string class in C++

Viewed 128

In the following C++ code, there should be three heap allocations as in the swap() function one temporary string object is also created. Why there are only two heap allocations in this code?

Without using move semantics

#include <iostream>
#include <unordered_map>

using namespace std;


static uint32_t allocations = 0;

void *operator new(size_t size)
{
    allocations++;
    cout << "Allocating " << size << " bytes\n";
    return malloc(size);
}


void swapUsingMove(string& arg1, string& arg2)
{
    string temp = arg1;
    arg1 = arg2;
    arg2 = temp;
    cout << allocations << endl;
}

int main()
{
    string str1{"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
    string str2{"ZYXWVUTSRQPONMLKJIHGFEDCBA"};

    swapUsingMove(str1, str2);
    cout << str1 << " " << str2;
    return 0;
}

Output

Allocating 51 bytes
Allocating 51 bytes
2
ZYXWVUTSRQPONMLKJIHGFEDCBA ABCDEFGHIJKLMNOPQRSTUVWXYZ

By using move semantics

#include <iostream>
#include <unordered_map>

using namespace std;


static uint32_t allocations = 0;

void *operator new(size_t size)
{
    allocations++;
    cout << "Allocating " << size << " bytes\n";
    return malloc(size);
}


void swapUsingMove(string& arg1, string& arg2)
{
    string temp = move(arg1);
    arg1 = move(arg2);
    arg2 = move(temp);
    cout << allocations << endl;
}

int main()
{
    string str1{"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
    string str2{"ZYXWVUTSRQPONMLKJIHGFEDCBA"};

    swapUsingMove(str1, str2);
    cout << str1 << " " << str2;
    return 0;
}

Output

Allocating 51 bytes
Allocating 51 bytes
2
ZYXWVUTSRQPONMLKJIHGFEDCBA ABCDEFGHIJKLMNOPQRSTUVWXYZ

Even without using the move semantics, why there are only two heap allocations? Where does the temp string gets allocated memory? If there are two heap allocations in both the cases then what is the advantage of using std:: move() here?

1 Answers

You are likely using an implementation that behaves according to the C++98/03 standard and that implements copy-on-write for std::string.

Live demo: https://godbolt.org/z/rP7M77

If this is the case, your question should not be tagged with c++11, since copy-on-write is not permitted since then. (SSO is usually implemented instead, but this is a different story.)

If you switch to a newer GCC, you will see 3 allocations: https://godbolt.org/z/b5q1MM

Related