2013-10-04 16 views
0

我使用“放置新”来分配我的对象。我使用三种记忆清除方式。他们都是安全的吗?我可以得到内存泄漏吗?我使用三种内存清除方式。他们都是安全的吗?我可以得到内存泄漏吗?

#include <iostream> 
#include <exception> 
#include <vector> 
using namespace ::std; 

class A{ 
private: 
    double x; 
public: 
    A() : x(0) { cout << "A class; ptr: " << this << " created." << endl; } 
    ~A() { cout << "A class; ptr: " << this << " destroyed." << endl; } 
}; 

int main(int argc, char* argv[]) 
try{ 
    // 1. Creating of object in the necessary memory address 

    static_assert(sizeof(char) == 1, "Unexpected size of char."); 
    int x = -1; // Variants of memory clearing 
    while (x < 0 || x > 2) { 
     cout << "Variant (0,1,2): "; 
     cin >> x; 
    } 
    char* p = new char[sizeof(A)]; // some memory area... 

    A* a = new(p)A(); // Place my object in the 'p' address. 

    // Here is my basic work to do... 

    // Now I must to free my memory: 
    if(!x){ // First variant 
     delete a;   
    } 
    else if (x == 1){ // Second variant 
     delete reinterpret_cast<A*>(p); 
    } 
    else if (x == 2){ // Third variant 
     a->~A();   
     delete[] p; 
    } 
    else{ 
     throw runtime_error("Invalid variant!"); 
    } 
    a = nullptr; 
    p = nullptr; 

    cout << endl; 
} 
catch(exception& e){ 
    cerr << e.what() << endl; 
    return 1; 
} 
catch(...){ 
    cerr << "Unknown exception." << endl; 
    return 2; 
} 

谢谢。

+1

当你的问题简单地重复标题时,它通常意味着你没有足够的描述:p可能解释你的三个变体(我知道你的代码很短,但仍然有帮助) – keyser

+6

你应该**永远不会* *明确地调用析构函数!当实例超出范围或调用delete时,它们将自动调用。 –

+2

''char'需要1个字节长的标准,断言是多余的。 – 2013-10-04 13:19:24

回答

3

delete[]和明确的析构函数调用的变体是正确的,因为它是你如何分配的镜面反射/构建它:

char* p = new char[sizeof(A)]; 
A* a = new(p)A(); 
... 
a->~A();   
delete[] p; 

但是,如果你没有很好的理由使用放置新的,考虑简单而直接:

A* a = new A(); 
... 
delete a; 

虽然delete应该呼吁每个newdelete[]每一个new[],因为你分配的0阵列s,第二个选项似乎不是很合理,但仍然合法(只要您确定内存块的大小真的等于sizeof(A),并且存在此类型的有效对象A即可阵列):

char* p = new char[sizeof(A)]; 
delete reinterpret_cast<A*>(p); 

另外请注意,下面的行是完全无用的:

static_assert(sizeof(char) == 1, "Unexpected size of char."); 

,因为它是由标准保证sizeof(char)总是返回1.

+0

>避免这样做,只是做... 我知道。我的问题是关于其他。 –

+0

>重要的是要知道,每个新的[]都应该为每个新的[]删除[],并删除[]。如果你使用新的[],然后尝试释放这个内存使用删除... 我知道。我的指针指向相同的内存地址。禁止为同一个指针调用delete \ delete []两次。 –

+0

@Bush:第二个选项依赖于两个事实:1.p指向的内存块的大小等于sizeof(A),2.一个有效的对象存储在这个内存中,这样将调用适当的析构函数。 – LihO

1

第三个变体是删除对象并清除已分配内存的正确方法。