繁体   English   中英

调用delete []会破坏我的C ++程序

[英]Calling delete[] breaks my C++ program

更新:感谢您的快速答复。 看来我已经发布了旧版本的代码。 除了参数化的构造函数外,其他所有内容均相同。 如您所见,代码中存在一些缺陷,但是请记住,我还没有完全完成此工作。 目前,我更担心数组,因为这是昨天引入的新概念。 我尝试了几种不同的方法,并进行了数小时的研究。 大多数响应都说只使用向量类,但这是用于家庭作业的,这有助于我们了解内存分配和动态数组。 目前,这是我的.cpp和.h文件,给我带来了问题。 每次触发删除(或清除功能)操作时,都会发生错误,指出blahblah.exe已触发断点。

MyVector.h

#pragma once

class MyVector
{
private:
    int arraySize; 
    int arrayCapacity;
    int* theData;
    void grow();

public:
    MyVector();
    MyVector(int n);
    int size() const;
    int capacity() const;
    void clear();
    void push_back(int n);
    int& at(int n);
    ~MyVector();
};

MyVector.cpp

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

    MyVector::MyVector()
    {
    arraySize = 0;
    arrayCapacity = 0; 
    theData = new int[0];
    }
    MyVector::MyVector(int capacityIn)
    {
    theData = new int [capacityIn];
    arraySize = 0;
    arrayCapacity = 0;
    }
    int MyVector::size() const
    {
    return arraySize;
    }
    int MyVector::capacity() const
    {
    return arrayCapacity;
    }
    void MyVector::clear()
    {
        delete [] theData;
        theData = nullptr;
    }
    void MyVector::push_back(int n)
    {
        if (arrayCapacity==0)
        {
        arrayCapacity++;
        MyVector(arrayCapacity);
    }
    if (arraySize == arrayCapacity)
    {
        grow();
        MyVector(arrayCapacity);
    }
    theData[arraySize] = n;
    arraySize++;
}
int& MyVector::at(int index)
{
    if (index >= 0 && index<arraySize)
    {
        return (theData[index]);
    }
    else
    {
        throw index;
    }
}
void MyVector::grow()
{
    arrayCapacity = arrayCapacity + arrayCapacity;
}

MyVector::~MyVector()
{
    if (theData != nullptr)
    {
        clear();
    }
}

您有很多问题,我已经可以看到:

  1. 您不应像这样显式调用构造函数。 它没有按照您的想法做。 将分配放入真实的成员函数中。
  2. 每次“增长”数组时,您都只是分配新数组,这会导致泄漏,因为之前的指针没有被删除。
  3. 您要问的主要问题:您甚至没有将分配的指针存储在构造函数中。 更改int* theData = new int [capacityIn]; theData = new int [capacityIn]; 例如,您在第一个构造函数中做的正确。
  4. 您还没有初始化arraySizearrayCapacity在你的第二个构造函数( MyVector(int)

刺针:

  1. 删除之前,无需检查nullptr
  2. 不需要new int[0] 您永远不要访问内存,因此只需将其初始化为nullptr

这里:

MyVector::MyVector(int capacityIn)
{
  int* theData = new int [capacityIn];
}

您声明一个局部指针theData ,该指针theData了当前对象的theData数据成员, theData初始化它。 从那里开始,所有赌注都禁止使用它,纯属偶然,因为它是delete[]程序最终崩溃的地方。

MyVector::MyVector(int capacityIn)
{
  theData = new int [capacityIn];
}

相反,和arraySizearrayCapacity将不得不以及初始化。

除此之外,您还会遇到这样的问题

MyVector(arrayCapacity);

push_back函数中分配一个MyVector类型的临时对象,该对象(几乎)立即被再次销毁; 它不会更改当前对象。

这导致您无法解决的问题:

int* theData = new int [capacityIn];

您在说:“请定义一个整数指针...”,依此类推。 成员变量不同于您在方法内部定义的变量。 这样做是没有意义的。 相反,您应该这样做:

theData = new int [capacityIn];

或者,仅出于教育目的(为了使您理解,我们将其分配给成员变量):

this->theData = new int [capacityIn];

另外(某些观点可能并不那么重要,但由于您是新手,所以我想指出这些观点):

  1. 请在第二个构造函数中设置其他变量,看来您已经忘记这样做了。

     MyVector::MyVector(int capacityIn) { theData = new int [capacityIn]; arraySize = capacityIn; arrayCapacity = capacityIn; } 
  2. 您应该使用有意义的名称,您绝对应该避免使用theData http://petdance.com/2012/04/the-worlds-two-worst-variable-names/

  3. 您的方法应以动词开头,例如getDimension() getCapacity()等。
  4. 构造函数是... 构造函数 ,这意味着在构造创建项目时都将调用它们。 您绝对不应该以任何方式显式调用构造函数。
  5. 这是一条基本规则:每当您使用new命令访问内存时,都应在一段时间后调用delete 您的代码存在严重的内存泄漏。

我也许可以为您提供更多帮助,但是我无法完全理解您要通过某些方法(即grow()pushBack()

通过构造函数体内的赋值语句初始化变量的样式不好。 相反,应在输入构造函数主体之前初始化变量。

您可以通过使用成员初始化器列表或在类定义中提供默认值来执行此操作。 后者似乎在这里最简单:

class MyVector
{
private:
    int arraySize = 0;
    int arrayCapacity = 0;
    int* theData = nullptr;
    // ....

然后在构造函数中,而不是复制代码,您应该利用现有函数来执行相同的操作:

MyVector::MyVector(int capacityIn)
{
     // call function which increases capacity to match capacityIn.
}

当前,您实际上没有增加容量的功能,因此您需要添加一个。 grow()函数使int变量增加,但是您不分配更多的内存,因此这只会导致您的代码写在实际分配的空间的末尾)。

它可能看起来像:

void grow( int newCapacity )
{
    if ( newCapacity < arrayCapacity )
        return;   // we do not need to shrink

    int *newData = new int [new_capacity];
    if ( arraySize > 0 )
        std::copy(arrayData, arrayData + arraySize, newData);
    delete[] arrayData;
    newData = arrayData;
}

然后,您可以修改grow() (如果您仍然想要保留它)和push_back()以也调用此函数。


注意, clear()函数只需要执行arraySize = 0; 它不需要释放任何内存。 您可以将该容量留作将来使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM