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

IntegerSet类堆内存损坏错误原因及修复方案咨询

修复IntegerSet类的堆内存损坏与功能异常问题

核心问题分析与修复步骤

1. 无参构造创建空集合导致越界访问

unionOfSets和intersectionOfSets中,原代码用new IntegerSet()创建默认size为0的集合,但后续插入原集合的元素(索引0~2)时,会直接访问超出数组范围的内存,触发堆损坏。

修复:创建新集合时取两个输入集合的最大size,确保能容纳所有可能的元素:

IntegerSet* IntegerSet::unionOfSets(const IntegerSet &otherSet) const
{
    int newSize = max(setSize, otherSet.setSize);
    IntegerSet* thirdSet = new IntegerSet(newSize);

    for (int i = 0; i < newSize; ++i)
    {
        bool thisHas = (i < setSize) ? (setArray[i] == 1) : false;
        bool otherHas = (i < otherSet.setSize) ? (otherSet.setArray[i] == 1) : false;
        
        if (thisHas || otherHas)
        {
            thirdSet->insertElement(i);
        }
    }
    return thirdSet;
}

IntegerSet* IntegerSet::intersectionOfSets(const IntegerSet &otherSet) const
{
    int newSize = max(setSize, otherSet.setSize);
    IntegerSet* extraSet = new IntegerSet(newSize);

    for (int i = 0; i < newSize; ++i)
    {
        bool thisHas = (i < setSize) ? (setArray[i] == 1) : false;
        bool otherHas = (i < otherSet.setSize) ? (otherSet.setArray[i] == 1) : false;
        
        if (thisHas && otherHas)
        {
            extraSet->insertElement(i);
        }
    }

    return extraSet;
}

2. 元素操作的索引边界错误

原insertElement和deleteElement中,判断条件k <= setSize允许访问数组的越界索引(数组有效索引为0~setSize-1),直接导致堆内存损坏。

修复:将条件改为k < setSize:

bool IntegerSet::insertElement(int k) 
{
    if (k < setSize && k >= 0)
    {
        setArray[k] = 1;
        return true;
    }
    else
        return false;
}

bool IntegerSet::deleteElement(int m)
{
    if (m < setSize && m >= 0)
    {
        setArray[m] = 0;
        return true;
    }
    else
        return false;
}

3. isEqual函数的逻辑漏洞

原函数未判断两个集合的size是否相等,直接比较元素,导致size不同的集合可能被误判为相等。

修复:先判断size是否一致,再比较元素:

bool IntegerSet::isEqual(const IntegerSet &otherSet) const
{
    if (setSize != otherSet.setSize)
        return false;
        
    for (int i = 0; i < setSize; ++i)
    {
        if (setArray[i] != otherSet.setArray[i]) 
            return false;
    }
    return true;
}

4. 测试代码的冗余操作

测试代码中while循环已完成有效插入,后续重复调用insertElement属于冗余,直接删除即可。

修复后的完整代码

头文件(IntegerSet.h)

#ifndef INTEGERSET_H
#define INTEGERSET_H

class IntegerSet
{
private:
    int *setArray;
    int setSize;

public:
    IntegerSet(int = 0);
    IntegerSet(const IntegerSet&);
    ~IntegerSet();

    IntegerSet* unionOfSets(const IntegerSet&) const;
    IntegerSet* intersectionOfSets(const IntegerSet&) const;

    bool insertElement(int);
    bool deleteElement(int);
    void printSet() const;

    bool isEqual(const IntegerSet&) const;

};

#endif

源文件(IntegerSet.cpp)

#include "IntegerSet.h"
#include <iostream>
#include <algorithm>
using namespace std;

IntegerSet::IntegerSet(int size)
{
    setArray = new int[size];
    setSize = size;

    for (int i = 0; i < size; ++i)
    {
        setArray[i] = 0;
    }
}

IntegerSet::IntegerSet(const IntegerSet &setToCopy) 
    : setSize(setToCopy.setSize)
{
    setArray = new int[setSize];

    for (int i = 0; i < setSize; ++i)
    {
        setArray[i] = setToCopy.setArray[i];
    }
}

IntegerSet::~IntegerSet()
{
    delete[] setArray;
}

void IntegerSet::printSet() const
{
    bool hasElements = false;
    for (int i = 0; i < setSize; ++i)
    {
        if(setArray[i] == 1)
        {
            cout << i + 1 << " ";
            hasElements = true;
        }
    }
    if (!hasElements)
        cout << "Empty";
}

IntegerSet* IntegerSet::unionOfSets(const IntegerSet &otherSet) const
{
    int newSize = max(setSize, otherSet.setSize);
    IntegerSet* thirdSet = new IntegerSet(newSize);

    for (int i = 0; i < newSize; ++i)
    {
        bool thisHas = (i < setSize) ? (setArray[i] == 1) : false;
        bool otherHas = (i < otherSet.setSize) ? (otherSet.setArray[i] == 1) : false;
        
        if (thisHas || otherHas)
        {
            thirdSet->insertElement(i);
        }
    }
    return thirdSet;
}

IntegerSet* IntegerSet::intersectionOfSets(const IntegerSet &otherSet) const
{
    int newSize = max(setSize, otherSet.setSize);
    IntegerSet* extraSet = new IntegerSet(newSize);

    for (int i = 0; i < newSize; ++i)
    {
        bool thisHas = (i < setSize) ? (setArray[i] == 1) : false;
        bool otherHas = (i < otherSet.setSize) ? (otherSet.setArray[i] == 1) : false;
        
        if (thisHas && otherHas)
        {
            extraSet->insertElement(i);
        }
    }

    return extraSet;
}

bool IntegerSet::insertElement(int k) 
{
    if (k < setSize && k >= 0)
    {
        setArray[k] = 1;
        return true;
    }
    else
        return false;
}

bool IntegerSet::deleteElement(int m)
{
    if (m < setSize && m >= 0)
    {
        setArray[m] = 0;
        return true;
    }
    else
        return false;
}

bool IntegerSet::isEqual(const IntegerSet &otherSet) const
{
    if (setSize != otherSet.setSize)
        return false;
        
    for (int i = 0; i < setSize; ++i)
    {
        if (setArray[i] != otherSet.setArray[i]) 
            return false;
    }
    return true;
}

测试文件(main.cpp)

#include "IntegerSet.h"
#include <iostream>
using namespace std;

int main()
{
    int input;
    IntegerSet set1(3);
    IntegerSet set2(3);
    IntegerSet* set3 = nullptr;
    IntegerSet* set4 = nullptr;

    cout << "Enter a number between 1 and 3 to add to the first set: ";
    cin >> input;
    while (!set1.insertElement(input - 1))
    {
        cout << "\nThat is an invalid number. Please enter a number between 1 and 3: ";
        cin >> input;
    }

    cout << "Enter a number between 1 and 3 to add to the second set: ";
    cin >> input;
    while (!set2.insertElement(input - 1))
    {
        cout << "\nThat is an invalid number. Please enter a number between 1 and 3: ";
        cin >> input;
    }

    cout << "Set 1 is: {";
    set1.printSet();
    cout << "}\nSet 2 is: {";
    set2.printSet();
    cout << "}\n" << endl; 

    set3 = set1.unionOfSets(set2);
    set4 = set1.intersectionOfSets(set2);

    cout << "The union of Set 1 and Set 2: " << endl;
    cout << "Set 3 - {";    
    set3->printSet();
    cout << "}" << endl;

    cout << "The intersection of Set 1 and Set 2: " << endl;
    cout << "Set 4 - {";    
    set4->printSet();
    cout << "}" << endl;
    
    if (set1.isEqual(set2))
        cout << "Set 1 and Set 2 are equal" << endl;
    else
        cout << "Set 1 and Set 2 are not equal" << endl;

    set3->deleteElement(1);
    set4->deleteElement(1);

    cout << "\nAfter removing 2 from Set 3 and Set 4" << endl
         << "Set 3 is now - {";
    set3->printSet();
    cout << "}" << endl;
    cout << "Set 4 is now - {";
    set4->printSet();
    cout << "}" << endl;

    delete set3;
    delete set4;

    system("PAUSE");
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 10:05:54