在下面的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