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

使用void指针生成无重复枚举数组出现重复,代码何处有误?

问题分析与修复方案

嘿,我帮你找出问题所在啦!你遇到的重复元素问题,核心是重复检查逻辑完全失效,还有几处小的逻辑冗余,下面一步步给你拆解说明:

1. 最关键的错误:重复检查比错了对象

你的isDuplicate函数里直接用*q == p做比较——但每个getAFruitVP()都会通过new Fruit创建一个全新的对象,所以每个指针的内存地址都是独一无二的!哪怕两个指针指向的枚举值完全相同,它们的地址也不一样,导致*q == p永远返回false,重复检查根本起不到作用。

修正后的isDuplicate函数

我们需要把VoidPtr强制转换成Fruit*,然后比较指针指向的实际枚举值,而不是指针本身:

bool isDuplicate(VoidPtr *vpArray, int size, VoidPtr p) {
    Fruit* target = static_cast<Fruit*>(p);
    VoidPtr *q = &vpArray[0];
    for(int j = 0; j < size; j++) {
        Fruit* current = static_cast<Fruit*>(*q);
        // 比较枚举值,而非指针地址
        if (*current == *target) {
            return true;
        }
        ++q;
    }
    return false;
}

2. constructVPArray里的冗余赋值

看这段代码:

*p = getAFruitVP ();
do {
    *p = getAFruitVP ();
}while (isDuplicate(vpArray, i, *p));

你先给*p赋值了一次,然后立刻在do块里又重新赋值覆盖了它,这完全是多余的。而且当i=0时,isDuplicate的size参数是0,循环不会执行,直接返回false,所以我们只需要保留do-while内部的赋值即可:

修正后的constructVPArray函数

void constructVPArray (VoidPtr *vpArray, int size) {
    VoidPtr *p = &vpArray[0];
    for (int i = 0; i < size; i++) {
        do {
            *p = getAFruitVP();
        } while (isDuplicate(vpArray, i, *p));
        ++p;
    }
}

3. 额外注意:MAXNO的值要匹配枚举数量

你的getAFruitVP里用了rand() % MAXNO,而你的Fruit枚举有7个成员(从Durian到Berry),所以MAXNO必须定义为7,否则会生成超出枚举范围的数值,导致未定义行为:

#define MAXNO 7

完整修正后的代码

我把所有修正点整合,还加上了内存释放的逻辑(避免内存泄漏)和测试输出:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

enum Fruit {Durian, Papaya, Apple, Orange, Mango, Jackfruit, Berry};
#define MAXNO 7
using VoidPtr = void*;

VoidPtr getAFruitVP () {
    int k = rand() % MAXNO;
    Fruit f = static_cast<Fruit>(k);
    Fruit *fruitPtr = new Fruit;
    *fruitPtr = f;
    VoidPtr vp = fruitPtr;
    return vp;
}

bool isDuplicate(VoidPtr *vpArray, int size, VoidPtr p) {
    Fruit* target = static_cast<Fruit*>(p);
    VoidPtr *q = &vpArray[0];
    for(int j = 0; j < size; j++) {
        Fruit* current = static_cast<Fruit*>(*q);
        if (*current == *target) {
            return true;
        }
        ++q;
    }
    return false;
}

void constructVPArray (VoidPtr *vpArray, int size) {
    VoidPtr *p = &vpArray[0];
    for (int i = 0; i < size; i++) {
        do {
            *p = getAFruitVP();
        } while (isDuplicate(vpArray, i, *p));
        ++p;
    }
}

int main () {
    srand(time(NULL));
    VoidPtr* vpArray;
    int size = rand() % 7; // 生成0-6的数组大小,你也可以改成1+rand()%7来生成1-7的大小
    vpArray = new VoidPtr[size];
    constructVPArray(vpArray, size);

    // 测试输出:打印数组中的枚举值
    cout << "Generated array (size " << size << "):" << endl;
    for (int i = 0; i < size; i++) {
        Fruit* f = static_cast<Fruit*>(vpArray[i]);
        cout << *f << endl;
    }

    // 释放内存,避免泄漏
    for (int i = 0; i < size; i++) {
        delete static_cast<Fruit*>(vpArray[i]);
    }
    delete[] vpArray;

    return 0;
}

最后提一句内存泄漏

你的原始代码没有释放new出来的Fruit对象和VoidPtr数组,这会导致内存泄漏,上面的完整代码已经补上了释放逻辑,记得使用动态分配的内存后一定要清理哦!

内容的提问来源于stack exchange,提问作者skyzhuzhu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:48:00