用指针传参可避免大数据拷贝,提升性能;推荐使用 mystruct* 或 const mystruct*,必要时用 const std::vector&;对齐敏感场景需确保地址对齐;间接排序用指针数组;筛选用双指针原地压缩;注意悬空指针与内存所有权。

用指针传参避免大数据拷贝
直接传原始数组指针比传 std::vector 或结构体对象快得多,尤其当每个元素是几十字节以上的结构体时。拷贝本身就会吃掉大量 CPU 和内存带宽,排序前就卡住了。
实操建议:
- 函数签名优先用
MyStruct* data或const MyStruct* data,而不是std::vector<mystruct></mystruct>值传参 - 如果必须用容器,传
const std::vector<mystruct>&</mystruct>引用,但注意其内部数据不一定是连续的(std::vector是连续的,std::list不是) - 对齐敏感场景(如 SIMD 加速排序),确保指针地址满足 16/32 字节对齐,可用
alignas(32) MyStruct*或std::aligned_alloc分配
用指针数组做间接排序,不动原始数据
原始数据量大、移动成本高(比如每个元素含 std::string 或动态分配字段),直接调用 std::sort 会触发大量构造/析构。改用「指针数组 + 自定义比较器」,只重排指针,不碰原数据。
示例:
std::vector<mystruct> data = /* ... */; std::vector<mystruct> ptrs(data.size()); for (size_t i = 0; i score score; // 按 score 升序 }); // ptrs 现在是按 score 排好的指针序列 </mystruct></mystruct>
注意:不能对 ptrs 做 push_back 或 resize 后还指望指针有效;若需筛选后保留顺序,先筛出索引再构建指针数组更安全。
筛选时用双指针原地压缩,避免额外分配
对百万级数组做条件筛选(如“保留 age > 30 的记录”),常见错误是新建 vector 逐个 push——这会触发多次内存重分配和元素拷贝。
更高效做法是用双指针原地覆盖:
MyStruct* end = data;
for (MyStruct* p = data; p != data + n; ++p) {
if (p->age > 30) {
*end++ = *p; // 浅拷贝;若含指针成员需深拷贝逻辑
}
}
size_t new_size = end - data; // 新的有效长度
关键点:
- 前提是
MyStruct支持 trivial copy(无自定义拷贝构造/析构),否则*end++ = *p可能漏掉资源管理逻辑 - 若结构体含
std::unique_ptr或std::string,必须用std::move(*p)而非*p,否则会复制内容 - 此法不保证稳定(相同 age 的相对顺序可能变),如需稳定,改用
std::stable_partition配合指针数组
注意指针生命周期和悬空风险
所有指针操作的前提是:你清楚谁拥有内存、何时释放、是否跨线程访问。大数据场景下最容易踩的坑不是性能,而是野指针。
典型陷阱:
- 把局部
std::vector的.data()指针存到别处,vector 一出作用域,指针立刻悬空 - 多线程中一个线程用
std::sort排指针数组,另一个线程同时修改原始数据——没加锁就是未定义行为 - 用
malloc分配内存但用delete[]释放,或反过来,尤其混用 C/C++ 内存接口时
真实项目里,宁可多花一点拷贝时间,也别省掉所有权标注(比如用 std::span<const mystruct></const> 替代裸指针);裸指针只在 hot path 且生命周期明确可控时才上。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











