RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1411763
Accepted
Everything
Everything
Asked:2022-07-20 01:33:39 +0000 UTC2022-07-20 01:33:39 +0000 UTC 2022-07-20 01:33:39 +0000 UTC

成对的对象解构器错误[关闭]

  • 772
关闭 这个问题是题外话。目前不接受回复。

5 个月前关闭。

  • 寻求调试帮助的问题(“为什么这段代码不起作用? ”)应该包括期望的行为、具体的问题或错误,以及在问题中重现它的最少代码。没有明确描述问题的问题对其他访问者毫无用处。请参阅如何创建一个最小的、独立的和可重现的示例。
  • 该问题是由不再复制的问题或错字引起的。虽然类似问题可能与本网站相关,但该问题的解决方案不太可能帮助未来的访问者。通常可以通过在发布问题之前编写和研究一个最小程序来重现问题来避免此类问题。
改进问题

该程序运行良好,但是当它结束(返回 0)并且解构器尝试成对处理类对象时,它会给出错误:

HEAP [program.exe]:指定给 RtlValidateHeap 的地址无效(0000021B54F40000, 0000021B54F50CA0)

这是完整的程序代码:

主文件

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


int main() {
    size_t temp = 0;

    IntSet intset1;
    IntSet intset2;



    intset1.pushBack(1);
    intset1.pushBack(2);
    intset1.pushBack(2);
    intset1.pushBack(5);
    intset1.pushBack(6);    // [1, 2, 5, 6]

    intset2.pushBack(6);
    intset2.pushBack(8);
    intset2.pushBack(2);
    intset2.pushBack(15);
    intset2.pushBack(27);   // [6, 8, 2, 15, 27]

    IntSet* intset3 = intset1.relative_complement(intset2); // [1, 2, 5, 6] / [6, 8, 2, 15, 27] = [1, 5]
    IntSet* intset4 = intset1.union_(intset2);  // [1, 2, 5, 6] + [6, 8, 2, 15, 27] = [1, 2, 5, 6, 8, 15, 27]

    pair<IntSet, IntSet> p = intset1.even_odd_division(intset2);


    temp = intset3->size();
    for (size_t i = 0; i < temp; i++) {
        cout << (*intset3)[i] << std::endl;
    }

    cout << "\n" << std::endl;

    temp = intset4->size();
    for (size_t i = 0; i < temp; i++) {
        cout << (*intset4)[i] << std::endl;
    }

    return 0;
}

整数集.h

#ifndef INT_SET_H
#define INT_SET_H


class IntSet {
public:
    IntSet();
    ~IntSet();
public:
    size_t size() const;
public:
    void pushBack(const int value);
    void remove(size_t index);
    int search(int num);
    IntSet* union_(IntSet& object_1);
    IntSet* relative_complement(IntSet& object_1);
    std::pair<IntSet, IntSet> even_odd_division(IntSet& object_1);
public:
    int operator[](size_t index);
private:
    int* arr_;
    size_t size_{};
    size_t capacity_{};

    void addMemory();
};

#endif // !INT_SET_H

整数集.cpp

#include <utility>
#include "IntSet.h"

void IntSet::pushBack(const int value) {
    if (search(value) == -1) {
        if (size_ >= capacity_) addMemory();
        arr_[size_++] = value;
    }
}

void IntSet::remove(size_t index) {
    for (size_t i = index + 1; i < size_; ++i) {
        arr_[i - 1] = arr_[i];
    }
    --size_;
}

int IntSet::search(int num) {
    for (size_t i = 0; i < size_; i++) {
        if (arr_[i] == num) {
            return (int)i;
        }
    }
    return -1;
}

IntSet* IntSet::union_(IntSet& object_1) {
    IntSet* NewIntSet = new IntSet;

    for (size_t i = 0; i < size(); i++)
    {
        NewIntSet->pushBack(arr_[i]);
    }
    for (size_t i = 0; i < object_1.size(); i++)
    {
        NewIntSet->pushBack(object_1.arr_[i]);
    }

    return NewIntSet;
}

IntSet* IntSet::relative_complement(IntSet& object_1) {
    IntSet* NewIntSet = new IntSet;
    int index = 0;

    for (size_t i = 0; i < size(); i++)
    {
        NewIntSet->pushBack(arr_[i]);
    }
    for (size_t i = 0; i < object_1.size(); i++)
    {
        index = NewIntSet->search(object_1.arr_[i]);
        if (index >= 0) NewIntSet->remove(index);
    }

    return NewIntSet;
}

void IntSet::addMemory() {
    capacity_ *= 2;
    int* tmp = arr_;
    arr_ = new int[capacity_];
    for (size_t i = 0; i < size_; ++i) arr_[i] = tmp[i];
    delete[] tmp;
}

int IntSet::operator[](size_t index) {
    return arr_[index];
}

size_t IntSet::size() const {
    return size_;
}

std::pair<IntSet, IntSet> IntSet::even_odd_division(IntSet& object_1) {
    IntSet EvenIntSet;
    IntSet OddIntSet;

    for (size_t i = 0; i < size(); i++) {
        if (arr_[i] % 2 == 0) EvenIntSet.pushBack(arr_[i]);
        else OddIntSet.pushBack(arr_[i]);
    }
    for (size_t i = 0; i < object_1.size(); i++) {
        if (object_1.arr_[i] % 2 == 0) EvenIntSet.pushBack(object_1.arr_[i]);
        else OddIntSet.pushBack(object_1.arr_[i]);
    }

    return std::make_pair(EvenIntSet, OddIntSet);;
}

IntSet::~IntSet() {
    delete arr_;
}

IntSet::IntSet() {
    arr_ = new int[1];
    capacity_ = 1;
}
c++
  • 2 2 个回答
  • 38 Views

2 个回答

  • Voted
  1. Best Answer
    DmitryK
    2022-07-20T05:07:32Z2022-07-20T05:07:32Z

    正如@Harry 所写,您的问题不在于析构函数,而在于类中没有复制构造函数和复制赋值运算符 - 即 您没有实施三的规则。 规则三
    当您自己不定义它时,编译器会创建一个默认的复制构造函数,该构造函数只是制作字段的副本。那些。只需将指针的值复制到缓冲区,而不复制缓冲区本身。

    std::pair<IntSet, IntSet> 
    IntSet::even_odd_division(IntSet& object_1) 
    {
        IntSet EvenIntSet;  // создали 2 локальных объекта, выделили память под массив
        IntSet OddIntSet;
    
        // заполнили их
        return std::make_pair(EvenIntSet, OddIntSet); // а теперь при создании пары делаются копии объектов - копируются указатели.
    } // а теперь первоначальные объекты уничтожаются и память под массивы освобождается
    
    main()
    {
      pair<IntSet, IntSet> p = intset1.even_odd_division(intset2); // если бы вы обратились к массивам из этой пары, то была бы ошибка
    
    // в конце программы пара уничтожается, вызываются деструкторы и пытаются освободить память, которая освобождена ранее
    }
    

    此外,您在这些函数中存在内存泄漏:

    IntSet* IntSet::union_(IntSet& object_1) 
    {
        IntSet* NewIntSet = new IntSet;
        return NewIntSet;
    }
    IntSet* IntSet::relative_complement(IntSet& object_1) 
    {
        IntSet* NewIntSet = new IntSet;
        return NewIntSet;
    }
    

    您正在动态创建对象,而不是销毁它们。只是程序小,负面影响来不及发生。
    此外,析构函数中的错误。为数组-分配内存时new[],需要通过deletedelete[]

    IntSet::~IntSet() {
        delete[] arr_;
    }
    
    • 2
  2. Everything
    2022-07-20T01:53:50Z2022-07-20T01:53:50Z

    当通过pair返回对象时,会调用一个解构器,当程序结束时也会调用它,试图删除不再存在的东西。

    • 0

相关问题

  • 编译器和模板处理

  • 指针。找到最小数量

  • C++,关于枚举类对象初始化的问题

  • 函数中的二维数组

  • 无法使用默认构造函数创建类对象

  • C++ 和循环依赖

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5