数组传递与返回优化咨询:移除重复元素的实现方案改进
更优的数组处理实现方案
嘿,你现在用void函数通过引用返回新分配数组的方式虽然能实现需求,但确实存在不少可以优化的点——尤其是手动内存管理很容易导致内存泄漏,而且接口的可读性也不算好。下面给你几个更符合现代C++风格、更安全的替代方案:
1. 返回标准容器(首推方案)
C++里的std::vector<T>是处理动态数组的最优选择,它会自动帮你搞定内存分配和释放,完全不用手动写new/delete,而且能直接对接标准库的各种算法,减少重复造轮子的麻烦。
比如你的去重功能可以改成这样:
#include <vector> #include <algorithm> template<class T> std::vector<T> eliminate(const std::vector<T>& niz) { if (niz.empty()) return {}; std::vector<T> podniz = niz; // 去重前需要先排序,std::unique只处理连续重复元素 std::sort(podniz.begin(), podniz.end()); // 移除连续重复元素,返回去重后的末尾迭代器 auto last = std::unique(podniz.begin(), podniz.end()); // 截断容器,只保留去重后的有效元素 podniz.erase(last, podniz.end()); return podniz; }
调用起来特别省心:
std::vector<int> arr = {1,2,2,3,3,3}; std::vector<int> unique_arr = eliminate(arr);
这个方案的优势很明显:
- 完全不用操心内存泄漏,容器会自动在生命周期结束时释放内存
- 接口直观,返回值直接就是处理后的结果,别人看代码一眼就能懂
- 直接复用标准库的成熟算法,减少自己写逻辑出错的概率
2. 返回智能指针(如果必须用原生数组)
要是因为某些限制必须用原生指针风格,那也别再用裸指针了,改用std::unique_ptr<T[]>——它是智能指针的一种,会自动在不需要的时候释放内存,从根源上避免泄漏问题。
示例代码如下:
#include <memory> #include <algorithm> #include <vector> template<class T> std::unique_ptr<T[]> eliminate(const T* niz, int duzina, int& out_length) { if (duzina <= 0) { out_length = 0; return nullptr; } // 先用vector做去重处理,方便复用标准算法 std::vector<T> temp(niz, niz + duzina); std::sort(temp.begin(), temp.end()); auto last = std::unique(temp.begin(), temp.end()); out_length = static_cast<int>(std::distance(temp.begin(), last)); // 用智能指针管理新数组 std::unique_ptr<T[]> podniz = std::make_unique<T[]>(out_length); std::copy(temp.begin(), last, podniz.get()); return podniz; }
调用的时候也不用手动释放内存:
int arr[] = {1,2,2,3,3,3}; int new_len = 0; auto unique_arr = eliminate(arr, 6, new_len); // 使用unique_arr的时候直接用get()获取裸指针就行,不用管释放
这个方案的好处是:
- 彻底告别手动
delete[],智能指针会自动处理内存释放 - 相比裸指针,所有权更明确,不容易出现野指针问题
3. 原地修改数组(允许修改原数组时用)
如果你的场景允许直接修改原数组,那完全不用分配新数组,直接在原数组上做去重操作,最后返回去重后的有效长度就行,这样效率最高:
#include <algorithm> template<class T> int eliminate_inplace(T* niz, int duzina) { if (duzina <= 0) return 0; std::sort(niz, niz + duzina); auto last = std::unique(niz, niz + duzina); return static_cast<int>(std::distance(niz, last)); }
调用方式也很简单:
int arr[] = {1,2,2,3,3,3}; int valid_len = eliminate_inplace(arr, 6); // 现在arr的前valid_len个元素就是去重后的结果
这个方案的优势:
- 不需要额外分配内存,内存开销最小,效率最高
- 接口简洁,只返回有效长度,调用者直接使用原数组的前N个元素即可
对原实现的小提醒
如果实在要坚持用原来的裸指针方式,一定要记得在调用完函数后手动调用delete[] podniz,不然肯定会造成内存泄漏。比如:
int* unique_arr = nullptr; eliminate(arr, 6, unique_arr); // 使用unique_arr处理业务... delete[] unique_arr; // 必须手动释放,千万不能忘!
但这种方式太容易出错了,在现代C++开发里真的不推荐使用。
内容的提问来源于stack exchange,提问作者Lazar Šćekić
相关产品推荐
相关产品推荐

