【问题标题】:Heap Corruption Detected C++ Custom Vector检测到堆损坏 C++ 自定义向量
【发布时间】:2015-07-15 16:28:11
【问题描述】:

嘿,我正在重新学习我参加的课程中的一些旧项目,当我重做这个项目时,当我在驱动程序中调用 clear() 函数时,我不断收到此错误,

检测到堆损坏:在 Normal 块之后 (#142) CRT 检测到应用程序在 HEAP 缓冲区结束后写入内存

这是我的自定义 Vector 类

#include "MyVector.h"

//insert header files
#include <iostream>
#include <string>

//setup access to necessary libraries
using namespace std;

MyVector::MyVector()
{
    // initialize member data
    size = 0;
    capacity = 2;

    //initialize new array
    classArray = new int[capacity];
}

MyVector::MyVector(int maxCapacity)
{
    // initialize member data
    size = 0;
    capacity = maxCapacity;

    // initialize new array
    classArray = new int[capacity];
}

MyVector::~MyVector()
{
    if (classArray != NULL)
    {
        delete [] classArray;
        classArray = NULL;
    }
}

int MyVector::getSize()
{
    return size;
}

int MyVector::getCapacity()
{
    return capacity;
}

void MyVector::clear()
{
    // delete the array
    delete[] classArray;

    // reinitialize the array
    capacity = 2;
    size = 0;

    classArray = new int[capacity];
}

void MyVector::push_back(int n)
{
    if (size > capacity)
    {
        // setup the special case of an array with 0 elements
        if (size == 0)
        {
            clear();
        }
        else
        {
            // declare a temporary pointer and allocate a new array
            capacity = capacity * 2;
            int* tempArray = new int[capacity];

            // copy the values from the old array to the temporary array
            for (int i = 0; i < size; i++)
            {
                tempArray[i] = classArray[i];
            }

            // call the destructor
            delete[] classArray;

            // assign the classArray pointer to the new array
            classArray = tempArray;
        }
    }

    // pushback a new value to the array
    classArray[size] = n;

    // increment size
    size++;
}

int MyVector::at(int n)
{
    // check if n is within the bounds of the array
    if (n >= size)
    {
        throw n;
    }

    // if not return the value of the index requested
    else
    {
        return classArray[n];
    }
}

这是我的驱动程序代码,

//insert header files
#include <iostream>
#include <string>
#include "MyVector.h"

//setup access to necessary libraries
using namespace std;

//declare constants
#pragma region Constants
const int TEST_VALUE1 = 21;
const int TEST_VALUE2 = 31;
const int TEST_VALUE3 = 41;

const int MAX = 12;
#pragma endregion

int main()
{
    // Create a default vector 
    MyVector sam;

    // push some data into sam
    cout << "\nPushing three values into sam";
    sam.push_back(TEST_VALUE1);
    sam.push_back(TEST_VALUE2);
    sam.push_back(TEST_VALUE3);

    cout << "\nThe values in sam are: ";

    // test for out of bounds condition here
    // and test exception 
    for (int i = 0; i < sam.getSize() + 1; i++)
    {
        try
        {
            cout << sam.at(i) << " ";
        }
        catch (int badIndex)
        {
            cout << "\nOut of bounds at index " << badIndex << endl;
        }
    }
    cout << "\n--------------\n";

    // clear sam and display its size and capacity
    sam.clear(); //********ERROR BEING THROWN HERE*********
    cout << "\nsam has been cleared.";
    cout << "\nSam's size is now " << sam.getSize();
    cout << "\nSam's capacity is now " << sam.getCapacity() << endl;
    cout << "---------------\n";

    // Push 12 values into the vector - it should grow
    cout << "\nPush 12 values into sam.";
    for (int i = 0; i < MAX; i++)
        sam.push_back(i);

    cout << "\nSam's size is now " << sam.getSize();
    cout << "\nSam's capcacity is now " << sam.getCapacity() << endl;
    cout << "---------------\n";

    cout << "\nTest to see if contents are correct...";
    // display the values in the vector
    for (int i = 0; i < sam.getSize(); i++)
    {

        cout << sam.at(i) << " ";
    }
    cout << "\n--------------\n";

    cout << "\n\nTest Complete...";

    cout << endl;
    system("PAUSE");
    return 0;
}

我已经多次来回查看我的旧项目,但我不明白为什么在尝试删除某些内容时会出现此错误。我的意思是,当我尝试分配无法分配但未删除的东西时,这听起来通常会发生?

任何帮助表示感谢!

【问题讨论】:

  • 请浏览“C++ Rule of 3”
  • Hey I am rehashing through a few old projects in a class I took 试试这个简单的 2 行程序:int main() { myVector sam; myVector sam2(sam); } 我刚刚打破了你的课。
  • @tokyo0709 你的clear 函数应该只是使大小= 0。它不需要释放内存。
  • @PaulMcKenzie 为什么我不需要释放内存?当程序退出主块时,析构函数是否就在那里并自动调用?
  • @tokyo0709 仔细查看您的代码。为什么每次调用clear 时都需要释放内存?您有 sizecapacity 成员。如果size 是0 而capacity 是100,那就这样吧。在size >= capacity 之前,您不会真正分配。您再次为自己节省了对释放和分配的无用调用,并将其推迟到 size 确实 >= capacity。当然析构函数必须真正释放内存,但这与clear不同。

标签: c++ vector dynamic-memory-allocation


【解决方案1】:

您的push_back 代码可以简化为:

if (size > capacity)
{
    // resize
}
classArray[size] = n;
size++;

但请注意,您以size == 0capacity == 2 开头,然后对push_back 进行三个调用。第三个是size == 2capacity == 2size &gt; capacity 仍然是 false,因此您将写入未初始化内存的 classArray[2](无需调整大小)。这是未定义的行为。

您想检查size &gt;= capacity 以调整大小。

请注意,您的类还有另一个严重的问题:您未能编写复制构造函数,因此如果您复制它,两个副本都会尝试释放相同的内存。请参阅三法则(在 C++11 中更新为五法则)。

【讨论】:

  • 哦,天哪,我之前就是这样设置的,然后出于某种原因,我认为它必须是公正的,尺寸 >= 容量 谢谢!顺便说一句,我可以只在我的 clear 函数中调用析构函数和默认构造函数而不是重复代码还是不允许这样做?
  • @tokyo0709 不,不是。
猜你喜欢
  • 2018-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-06
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
相关资源
最近更新 更多