【发布时间】:2021-03-14 17:52:24
【问题描述】:
在下面的 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 << " 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;
}
输出
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 << " 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;
}
输出
Allocating 51 bytes Allocating 51 bytes 2 ZYXWVUTSRQPONMLKJIHGFEDCBA ABCDEFGHIJKLMNOPQRSTUVWXYZ
即使不使用移动语义,为什么只有两个堆分配?临时字符串在哪里分配内存?如果在这两种情况下都有两个堆分配,那么在这里使用 std::move() 有什么好处?
【问题讨论】:
-
您能否向我们展示您实际上难以理解的程序(“不使用移动语义”)?还包括您从程序获得的实际输出,以及可能的预期输出。
-
@jtbandes 这不是关于 SSO 的,不要误导。
-
你用的是什么编译器?首先,我使用 gcc 和 clang 得到不同的输出(都启用了优化)
-
您是否查看了生成的代码以了解它的作用?也许编译器识别了“交换”模式并生成代码来交换指针?
-
@ArunSuryan: 什么版本的 GCC,你用什么命令行来编译?我无法在simple test cases with Godbolt 上复制;我得到了三个分配(虽然它们要小得多;27 个字节,而不是 51 个)。
标签: c++ string c++11 move swap