C++中字符串类中的堆分配



在下面的C++代码中,应该有三个堆分配,就像在swap()函数中一样,还会创建一个临时字符串对象。为什么这段代码中只有两个堆分配?

不使用移动语义

#include <iostream>
#include <unordered_map>
using namespace std;

static uint32_t allocations = 0;
void *operator new(size_t size)
{
allocations++;
cout << "Allocating " << size << " bytesn";
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;
}

输出

Allocating 51 bytes
Allocating 51 bytes
2
ZYXWVUTSRQPONMLKJIHGFEDCBA ABCDEFGHIJKLMNOPQRSTUVWXYZ

通过使用移动语义

#include <iostream>
#include <unordered_map>
using namespace std;

static uint32_t allocations = 0;
void *operator new(size_t size)
{
allocations++;
cout << "Allocating " << size << " bytesn";
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;
}

输出

Allocating 51 bytes
Allocating 51 bytes
2
ZYXWVUTSRQPONMLKJIHGFEDCBA ABCDEFGHIJKLMNOPQRSTUVWXYZ

即使不使用移动语义,为什么只有两个堆分配?临时字符串从哪里获得分配的内存?如果在这两种情况下都有两个堆分配,那么在这里使用std::move((有什么好处?

您可能使用的实现符合C++98/03标准,并且为std::string实现了写时复制

现场演示:https://godbolt.org/z/rP7M77

如果是这种情况,您的问题不应标记为c++11,因为从那时起就不允许写时复制。(SSO通常被实现,但这是另一回事。(

如果您切换到较新的GCC,您将看到3个分配:https://godbolt.org/z/b5q1MM

相关内容

  • 没有找到相关文章

最新更新