2015-10-13 89 views
1

我有一个类与构造函数和析构函数和一个其他方法。 当我创建这个类的新实例,然后它调用析构函数的地方,我不知道为什么。堆 - 构造函数和析构函数,内存分配

class Heap 
{ 
private: 
    int *heap; 
    int size; 
    int heap_size; 
public: 
    Heap(int new_size) 
    { 
     size = new_size; 
     heap_size = 0; 
     heap = (int*)malloc(new_size*sizeof(int)); //??? 
     //heap = new int[new_size]; //??? 
    } 
    ~Heap() 
    { 
     free(heap); 
    } 
    void add(int alfa) 
    { 
    // something 
    } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    srand(time(NULL)); 
    int k = rand() % 100 + 1; 
    Heap *name = &Heap(k); 
    Heap *name2 = new Heap(k); //what's the diffrence? 
    while (k > 0) 
    { 
     name->add(rand()); // doesn't work, because destructor is called before 
     k--; 
    } 
    system("pause"); 
    return 0; 
} 
+4

'&堆(k)'您正在返回临时地址。 –

+1

'main.cpp(31):warning C4238:使用非标准扩展:用作左值的类rvalue这应该是一个错误,但是微软的编译器默认破坏。永远不要忽视那个警告。 –

+2

为什么你在班内使用'malloc'而不是'new []'? (但是,如果可能的话,你应该使用'std :: vector'或'std :: array'代替原始内存分配)。 – crashmstr

回答

3

在这个过程中运行该非标准一段代码,其将最有可能产生未定义的行为 无论如何,这条线

Heap *name = &Heap(k); 

产生临时Heap对象在完整表达式的末尾被破坏。这导致析构函数被调用。

请注意,事实是,您的班级相当脆弱,因为它不遵循the rule of three (five)。复制Heap对象将导致双重删除。


1出于很好的理由,标准C++不允许使用临时地址。
2这种结构留给你一个悬挂指针。从技术上讲,取消引用name会导致未定义的行为。

+0

这是不合格的。 MS会不会改变完全破碎的默认值?它导致很多初学者写出可怕的错误,甚至不应该编译。 –

+0

@JonathanWakely对,我加了一个关于这个的笔记。 – juanchopanza

相关问题