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

时间:2015-02-22 22:32:09

标签: c++ arrays memory dynamic allocation

更新:感谢您的快速回复。我似乎发布了旧版本的代码。除参数化构造函数外,一切都保持不变。您可以看到代码中存在一些缺陷,但请记住,我还没有完全完成此操作。目前我更担心阵列,因为这是昨天推出的一个新概念。 我尝试了几种不同的东西,并研究了几个小时。大多数响应都说只使用向量类,但这是用于帮助我们理解内存分配和动态数组的功课。目前这是我的.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();
    }
}

4 个答案:

答案 0 :(得分:5)

我已经看到了很多问题:

  1. 您不应该像这样明确地调用构造函数。它没有做你的想法。将分配放在真正的成员函数中。
  2. 每次你&#34;成长&#34;你的数组,你只需要分配new,导致泄漏,因为之前的指针没有被删除。
  3. 您要问的主要问题:您甚至没有存储您在构造函数中分配的指针。将int* theData = new int [capacityIn];更改为theData = new int [capacityIn];。例如,您可以在第一个构造函数中正确执行此操作。
  4. 您没有在第二个构造函数(arraySize)中初始化arrayCapacityMyVector(int)
  5. 挑剔:

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

答案 1 :(得分:2)

下面:

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

声明一个本地指针theData,它隐藏当前对象的theData数据成员,使其保持未初始化状态。从那里开始,所有的赌注都在使用它,并且它是纯粹的偶然事件,它是你的程序最终崩溃的delete[]。写

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

相反,arraySizearrayCapacity也必须初始化。

除此之外,你还会遇到

的问题
MyVector(arrayCapacity);
push_back函数中的

分配一个类型MyVector的临时对象,它几乎立即被立即销毁;它不会改变当前的对象。

答案 2 :(得分:0)

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

int* theData = new int [capacityIn];

你说:&#34;请定义一个整数指针......&#34;等等。成员变量与您在方法中定义的变量不同;这样做是没有意义的。相反,你应该这样做:

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。您的代码有严重的内存泄漏。
  6. 我可能能够为您提供更多帮助,但我并不完全理解您在某些方法中想要实现的目标,即grow()pushBack()

答案 3 :(得分:0)

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

您可以使用member initializer list或在类定义中提供默认值来执行此操作。后者似乎最简单:

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;。它不需要释放任何记忆;你可以将这个容量留待将来使用。