使用C++移动语义时内存中发生了什么?以交换代码为例解析
关于swapWithMove函数的内存变化分析
首先要明确:int是C++中的平凡类型,它没有自定义的移动构造/赋值运算符,编译器生成的默认移动操作和拷贝操作完全等价——也就是说,对int用std::move()不会产生“偷取资源”的效果,只是做了一次值拷贝。这也是这个例子属于教学用非典型场景的原因,移动语义的真正价值体现在带堆资源的类型(比如std::string、std::vector)上。
下面一步步拆解swapWithMove执行时的内存变化:
初始状态
在main函数中:
x是栈上的int变量,内存地址假设为&x,存储值5y是栈上的int变量,内存地址假设为&y,存储值10- 调用
swapWithMove(x, y)时,形参a是x的左值引用(int&),b是y的左值引用——也就是说,a和x指向同一块内存,b和y指向同一块内存,没有新内存分配。
第一步:int temp = std::move(a);
std::move(a)的作用是把左值引用a(本质是x的别名)强制转换成int&&类型的右值引用,但这只是类型转换,没有修改任何内存内容。- 因为int的移动构造就是拷贝,所以
temp会在栈上分配新内存(地址&temp),并把a(也就是x)的值5拷贝到temp中。 - 此时状态:
x(a)=5,y(b)=10,temp=5,所有变量的内存值都没被清空。
第二步:a = std::move(b);
std::move(b)把b(y的别名)转换成右值引用,int的移动赋值同样等价于拷贝操作。- 把
b(y)的值10拷贝到a对应的内存(也就是x的内存)中。 - 此时状态:
x(a)=10,y(b)=10,temp=5。
第三步:b = std::move(temp);
std::move(temp)把temp转换成右值引用,执行拷贝赋值。- 把
temp的值5拷贝到b对应的内存(也就是y的内存)中。 - 此时状态:
x(a)=10,y(b)=5,temp=5。
函数结束后
swapWithMove执行完毕,栈上的局部变量temp被销毁,内存被释放。回到main函数中,x和y的值已经完成交换。
额外补充:移动语义的真正作用
如果把例子中的int换成带堆资源的类型(比如std::vector<int>),移动操作就会完全不同:
- 移动构造/赋值会直接转移原对象的堆内存指针,而不是拷贝整个堆数组
- 原对象会被置为“空”状态(比如vector的size变为0,data指针为nullptr)
- 这才是移动语义的核心价值:避免昂贵的资源拷贝,提升性能。
内容的提问来源于stack exchange,提问作者gvg
相关产品推荐
相关产品推荐

