如何正确多次引用指针?void指针集合并集拷贝异常求解
问题根源与解决方案
首先直接点出你遇到的问题核心:你的代码里int* temp只是声明了一个指针,但既没有初始化,也没有为它分配独立的内存空间。循环中你一直复用这个指针,每次赋值*temp = getElementI(...)都是在覆盖同一块内存的值,最后unionSet里所有元素的指针都指向这同一个内存地址,所以输出全是最后一次赋值的8——这不仅是逻辑错误,还存在野指针的严重风险(未初始化的指针指向随机内存,运行时可能直接崩溃)。
针对你的需求(不能用vector或排序,只能用原生方法),有两种可行的解决思路:
方案一:每次循环分配独立内存(安全优先)
如果需要并集的元素是集合A元素的独立副本(避免后续集合A修改影响并集),可以在每次循环中为temp分配新的int内存:
void findUnion(VoidPtr * aSet,VoidPtr * bSet,VoidPtr * unionSet,int sizea,int sizeb,int &sizec) { // 将集合A拷贝至集合C for(int i =0; i < sizea; i++) { int* temp = new int; // 每次循环创建新的int内存块 *temp = getElementI(aSet[i]); unionSet[i] = temp; } sizec = sizea; // 初始化并集的大小为集合A的大小 // 后续处理集合B的元素(检查是否已在并集中,不在则添加) for(int j = 0; j < sizeb; j++) { int bVal = getElementI(bSet[j]); bool exists = false; // 遍历并集,检查元素是否已存在 for(int k = 0; k < sizec; k++) { if(getElementI(unionSet[k]) == bVal) { exists = true; break; } } if(!exists) { int* newElem = new int; *newElem = bVal; unionSet[sizec] = newElem; sizec++; } } }
这种方式保证每个并集元素都有独立的内存,不会出现覆盖问题,也避免了野指针风险。
方案二:直接复用集合A的指针(高效优先)
如果集合A的元素在并集的整个生命周期内都不会被销毁或修改,那么可以直接拷贝集合A的指针,省去内存分配的开销:
void findUnion(VoidPtr * aSet,VoidPtr * bSet,VoidPtr * unionSet,int sizea,int sizeb,int &sizec) { // 将集合A拷贝至集合C:直接复用指针 for(int i =0; i < sizea; i++) { unionSet[i] = aSet[i]; } sizec = sizea; // 同样处理集合B的元素(检查存在性后添加) for(int j = 0; j < sizeb; j++) { int bVal = getElementI(bSet[j]); bool exists = false; for(int k = 0; k < sizec; k++) { if(getElementI(unionSet[k]) == bVal) { exists = true; break; } } if(!exists) { int* newElem = new int; *newElem = bVal; unionSet[sizec] = newElem; sizec++; } } }
注意:这种方式的前提是集合A的元素不会提前被delete,否则并集里的指针会变成野指针,导致程序崩溃或未定义行为。
最后提醒你:使用完并集后,记得遍历unionSet,逐个delete里面的指针,避免内存泄漏。
内容的提问来源于stack exchange,提问作者john tod
相关产品推荐
相关产品推荐

