您好:这款游戏可以开挂,确实是有挂的,很多玩家在...
2025-09-07 0
想象你要搬家 ——
而memcpy就是一家 “专业搬家公司”,不管你要搬的东西在储物柜(栈)还是仓库(堆),它都能按你说的 “搬多少字节”,原封不动从 “源地址” 搬到 “目标地址”。但这家公司有点 “死板”:只负责搬,不检查目标空间够不够,也不管源和目标地址是不是重叠 —— 搬坏了概不负责~
memcpy的函数原型长这样:
cpp
运行
void* memcpy(void* dest, const void* src, size_t n);
它的核心逻辑很简单:从src开始,连续复制n个字节到dest,像用复印机一页页复印文件,字节级精准复制。
栈上的变量(比如数组、基本类型)就像储物柜里的箱子,memcpy可以快速在相邻储物柜之间搬东西。
cpp
运行
#include <iostream>#include <cstring> // memcpy的“营业执照”在这里int main() { // 栈上的源数组(旧家:储物柜A) int src_stack[3] = {10, 20, 30}; // 每个int占4字节,共12字节 // 栈上的目标数组(新家:储物柜B,大小和源一样) int dest_stack[3]; // 未初始化,像空箱子 // 打印搬家前的新家(全是随机值,储物柜里的旧垃圾) std::cout << "搬家前的dest_stack:"; for (int i = 0; i < 3; i++) { std::cout << dest_stack[i] << " "; // 输出随机数,比如:-1217635216 32767 0 } std::cout << std::endl; // 调用memcpy搬家:从src_stack搬12字节到dest_stack(3个int) // 源和目标都在栈上,属于“短途搬家” memcpy(dest_stack, src_stack, sizeof(src_stack)); // sizeof算总字节数,省心 // 打印搬家后(新家东西和旧家一模一样) std::cout << "搬家后的dest_stack:"; for (int i = 0; i < 3; i++) { std::cout << dest_stack[i] << " "; // 输出:10 20 30 } std::cout << std::endl; // 验证内存地址(都在栈上,地址相近) std::cout << "src_stack地址:" << &src_stack << std::endl; // 比如:0x7ffd9a5b167c std::cout << "dest_stack地址:" << &dest_stack << std::endl; // 比如:0x7ffd9a5b1668(和上面很接近) return 0;}
bash
g++ stack_memcpy.cpp -o stack_memcpy -std=c++11./stack_memcpy # Linux/Mac# 或 stack_memcpy.exe(Windows)
堆上的内存(用new或malloc申请)就像自助仓库的隔间,memcpy也能在两个仓库隔间之间搬东西,只是 “路远点”(地址可能相差很大)。
cpp
运行
#include <iostream>#include <cstring>int main() { // 堆上的源数组(旧家:仓库A) int* src_heap = new int[3]{100, 200, 300}; // 申请12字节堆内存 // 堆上的目标数组(新家:仓库B,必须提前申请足够大的空间!) int* dest_heap = new int[3]; // 申请12字节堆内存,准备接收 // 打印搬家前的新家(堆上的随机值,仓库旧垃圾) std::cout << "搬家前的dest_heap:"; for (int i = 0; i < 3; i++) { std::cout << dest_heap[i] << " "; // 比如:4196128 0 4195776 } std::cout << std::endl; // 调用memcpy搬家:从堆上的src_heap搬12字节到堆上的dest_heap memcpy(dest_heap, src_heap, 3 * sizeof(int)); // 3个int,每个4字节 // 打印搬家后 std::cout << "搬家后的dest_heap:"; for (int i = 0; i < 3; i++) { std::cout << dest_heap[i] << " "; // 100 200 300 } std::cout << std::endl; // 验证内存地址(堆地址通常比栈大,且两个堆地址可能相差较远) std::cout << "src_heap地址:" << src_heap << std::endl; // 比如:0x55f9d999a2a0 std::cout << "dest_heap地址:" << dest_heap << std::endl; // 比如:0x55f9d999a2c0(和上面差几十字节) // 堆内存要手动释放(还仓库钥匙!) delete[] src_heap; delete[] dest_heap; return 0;}
bash
g++ heap_memcpy.cpp -o heap_memcpy -std=c++11./heap_memcpy
memcpy还能跨类型搬家:从栈搬到堆,或从堆搬到栈,就像从储物柜搬东西到仓库,反之亦然。
cpp
运行
#include <iostream>#include <cstring>int main() { // 1. 栈→堆:把栈上的数组搬到堆上 int stack_arr[2] = {1, 2}; // 栈上的源(8字节) int* heap_dest = new int[2]; // 堆上的目标(提前申请8字节) memcpy(heap_dest, stack_arr, sizeof(stack_arr)); // 栈→堆搬家 std::cout << "栈→堆结果:" << heap_dest[0] << ", " << heap_dest[1] << std::endl; // 1, 2 // 2. 堆→栈:把堆上的数组搬回栈上 int stack_dest[2]; // 栈上的目标 memcpy(stack_dest, heap_dest, 2 * sizeof(int)); // 堆→栈搬家 std::cout << "堆→栈结果:" << stack_dest[0] << ", " << stack_dest[1] << std::endl; // 1, 2 // 清理堆内存 delete[] heap_dest; return 0;}
plaintext
栈→堆结果:1, 2堆→栈结果:1, 2
如果源地址和目标地址有重叠(比如同一个数组内部复制),memcpy会出问题,就像搬家时新家和旧家在同一个隔间,东西还没搬完就被覆盖了。
cpp
运行
#include <iostream>#include <cstring>int main() { int arr[5] = {1, 2, 3, 4, 5}; // 栈上的数组(源和目标重叠) std::cout << "原数组:"; for (int i = 0; i < 5; i++) std::cout << arr[i] << " "; // 1 2 3 4 5 std::cout << std::endl; // 错误:用memcpy从arr[1]复制3个int到arr[2](地址重叠) memcpy(&arr[2], &arr[1], 3 * sizeof(int)); // 想把2,3,4复制到位置2,3,4,预期结果1 2 2 3 4 std::cout << "memcpy处理重叠后:"; for (int i = 0; i < 5; i++) std::cout << arr[i] << " "; // 实际结果:1 2 2 2 3(出错了!) std::cout << std::endl; // 正确:用memmove处理重叠(memmove是“智能搬家公司”,会先备份) int arr2[5] = {1, 2, 3, 4, 5}; memmove(&arr2[2], &arr2[1], 3 * sizeof(int)); // 安全处理重叠 std::cout << "memmove处理重叠后:"; for (int i = 0; i < 5; i++) std::cout << arr2[i] << " "; // 1 2 2 3 4(正确) std::cout << std::endl; return 0;}
plaintext
原数组:1 2 3 4 5 memcpy处理重叠后:1 2 2 2 3 memmove处理重叠后:1 2 2 3 4
把memcpy当 “傻瓜式搬家公司” 用就对了:给足空间、地址别重叠、类型要匹配,它就能高效完成任务~
本文用搬家公司的幽默类比,详解 C++ 中 memcpy 函数在栈内存和堆内存上的操作原理,通过 4 个案例展示同区复制、跨区复制及重叠内存处理等场景,分析其优缺点和使用注意事项,步骤清晰可实操,助你掌握 memcpy 的内存操作逻辑。
#C++ #memcpy #内存操作 #栈内存 #堆内存
相关文章
Cursor CEO 最新一期播客,讲述了他坎坷却传奇的创业旅程。一个 24 岁的年轻人,如何带领团队在短短一年时间中,把 Cursor 打造成年收入...
2025-09-07 0
现在人们打棋牌麻将谁不想赢?手机微乐麻将必赢神器但是手机棋牌麻将是这么好赢的吗?在手机上打棋牌麻将想赢,不仅需要运气,也需要技巧。掌握的棋牌麻将技巧就...
2025-09-07 0
作者:冯海泉(68Design id:296292)品牌方:CKPA全案出品:Mrfeng冯先生服务内容:详情页单品全案设计...
2025-09-07 0
AI的未来正展现出无可限量的潜力,逐步渗透到我们生活的每一个角落。从医疗、教育到金融、制造业,AI正在推动着各行各业的深刻变革。未来,AI将不再仅仅是...
2025-09-07 0
在桌面CPU领域英特尔和AMD都是无敌的存在,两者的“爱恨情仇”一直持续至今,在CPU“战场”的厮杀总是有来有回,你方唱罢我登场。CPU产品在不同的定...
2025-09-07 0
数码圈素有“金九银十”之说,2025年的千元机市场早已不是低配代名词,而是续航怪兽、性能神机和性价比屠夫的竞技场。步入9月,新一轮开学季让不少学生党都...
2025-09-07 0
发表评论