2013-11-28 29 views
-1

我想写一个类,其中包含一个双*数组,可以通过各种方式填充,在程序结束时,内存应该释放 - 唉,这是行不通的。C++析构函数解除分配问题

我得到了“programname.exe引发了一个断点”的通知,这导致我的main.cpp的最后一行 - 当我删除我的析构函数时它工作正常,所以我假设它必须用那个做点什么。

下面是相关代码:

.H

#pragma once 
using namespace std; 
#include <iostream> 
class polynom 
{ 
public: 
    polynom(int grad, double* arr); 
    polynom(int grad); 
    polynom(); 
    ~polynom(void); 
    polynom& operator=(polynom p); 
    friend ostream& operator<<(ostream& os, const polynom& p); 
private: 
    int grad; 
    double* arr; 
}; 

的.cpp

polynom::polynom(int grad, double* arr) 
{ 
    this->grad = grad; 
    this->arr = arr; 
} 

polynom::polynom(int grad) 
{ 
    this->grad = grad; 
    this->arr = new double[grad]; 
} 

polynom::polynom() 
{ 
    arr = NULL; 
} 

polynom::~polynom() 
{ 
    delete[] arr; 
} 

主要

void main() 
{ 
    double arr1[] = {5,0,1}; 
    double arr2[] = {3,2,1}; 
    polynom p1 = polynom(2, arr1); 
    polynom p2 = polynom(2, arr2); 
    system("pause"); 
} 

非常感谢!

+0

您试图删除堆栈分配的数组,这会使应用程序正常崩溃。你可能想避免使用原始指针,而是看看'td :: shared_ptr'和'std :: unique_ptr' – bobah

+0

你不能'删除'没有从'new'分配的内存 –

+0

这显然不是主要问题,但不要忘记定义一个副本。 – MaMazav

回答

2

以下是将堆栈定义的变量分配给polynom中的arr数组。

double arr1[] = {5,0,1}; 
double arr2[] = {3,2,1}; 
polynom p1 = polynom(2, arr1); 
polynom p2 = polynom(2, arr2); 

一旦多项式被破坏,它会删除这些指针...你可能不会这样写:

double arr1[] = {1,2,3}; 
delete arr1; 

同样的问题。

---更新

有两种可能的解决方案去解决这个问题:

  1. 接受用户数据的构造函数分配一个缓冲区,使副本

这是这是最安全的方式,因为对象内部的缓冲区被认为是安全的。在非常大的项目中,假设您不分配数百万个多项式对象,那么这将为您节省大量时间,在这种情况下,缓慢会成为问题。

  1. 构造标记的输入作为用户输入这意味着它没有将其删除的权利,调用者负责,要通过增加一个布尔值,如果设置发生

这工作为true(例如),析构函数不会删除缓冲区。

然而,有,用这种方法一个巨大的问题:如果你使用一个基于堆栈缓冲区并返回多项式,缓冲得到由return语句删除,您有一个bug ......

因此我不建议你使用这种方法。

---附注

你写polynom(2, arr1); ...注意,您必须在数组中的三个要素。我建议你使用sizeof()代替:polynom(sizeof(arr1)/sizeof(arr1[0]), arr1);

此外,正如其他答案所述,您希望重载polynom拷贝构造函数和复制赋值,因为两者都会破坏您的代码。不过,只要你不复制多项式,你就没问题。然而,就目前而言,您最终会使用默认设置,并且根本无法正常工作。

+0

有没有一种方法来分配堆栈定义的变量,仍然能够设置一个“正确的”析构函数? - 这种进入阵列的方法是由我的教授提出的。 –

+0

您必须分配一个新数组并复制您传递的数组的内容。或者使用'std :: vector'。 – paddy

+0

啊,谢谢,我相应地更改了2参数构造函数,现在它可以工作 –

3

您正在遇到三条规则。

如果你这样做,它将正常工作:

polynom p1(2, arr1); 
polynom p2(2, arr2); 

的问题是你的赋值运算符不重复的阵列,所以当你指定的本地临时,它就会立即销毁(与阵列一起)。然后,当你的本地人超出范围,他们尝试删除已被删除的指针。

而不是重写operator=,你应该复制构造函数polynom(const polynom&)。你很少需要覆盖operator=。复制构造函数也更通用 - 它允许您按值传递对象,而operator=仅适用于赋值。

在任何情况下,您都必须分配一个新数组并复制这些内容,而不是复制指针。你应该真的使用std::vector,你不会有这些问题。

+0

对不起,我不太理解 - 我改变了我的代码来说'polynom p1(2,arr1);'等等,但它仍然不起作用。覆盖=运算符是我的教授给出的一个限制。 –

+0

对不起,另一个答案提出了问题。我没有检查所有的构造函数。我指出了一个不同的问题。 – paddy