You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数组传递与返回优化咨询:移除重复元素的实现方案改进

更优的数组处理实现方案

嘿,你现在用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ć

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:07:08