2015-04-27 68 views
-5

考慮一個C++函數爲:內存分配兩難困境在C++

A* dum() 
{ 
    A* a = new A() 
    doSomethingOnA() 
    return a; 
} 

現在dum()被稱爲

A* b; 
b = dum(); 

我的問題是我們需要的內存分配給b嗎?

編輯:如果我做得一樣:

bool dum(A* a) 
{ 
    // A* a = new A() -- Is this needed? 
    doSomethingOnA() 
    return 1; 
} 

和達姆被稱爲

A* b = new A() 
dum(b); 
+4

你說的「指定內存」是什麼意思? – Borgleader

+1

沒有,'B'是''從達姆彈了'( )','因爲A'被指向的數據,和'B'將指向相同的地址然後'A' – Eun

+0

@Borgleader - 我的意思是perfoming b =新A() –

回答

1

你並不需要分配一個新的A()爲b,因爲通過調用b = dum(),你已經讓b指向與a相同的內存位置。請記住,通過使用指針,您不會將內容分配給b,您只分配一個內存位置地址。事實上,如果你做b = new A(),然後做b = dum(),你將首先丟失b指向的內存位置的引用,這會導致內存泄漏。

2

從RAII的角度來看,您不應該在dum之內分配並返回一個原始指針。

更好的選擇是:

  • 的std ::的unique_ptr達姆();
  • std :: shared_ptr dum();
  • void dum(A &);

前兩個返回一個託管指針,而第三個指望可能是堆棧或堆變量的引用。

另一個好選項由值返回(這應該給一個編譯器優化代碼,如果`甲寫得):

  • 甲達姆();

參見:

+0

@πάνταῥεῖ而且它應該是公正的(A返回一個值的功能 - 非本地) –

+0

不好意思啊,我誤解你的樣品我認爲它應該簡單地展示在A'的'堆棧分配(這將是一個很好的提點)。 –

+0

你應該保持我的其他修改,關於源代碼表示。 –

0

兩個你的例子是合法的。有其他人已經建議的更好的方法,但原則上你的代碼是好的。我試圖添加一些評論來解釋發生了什麼。希望澄清它。

而且「不 - 你不需要爲b保留內存」。編譯器會爲你處理它。

你的第一示例

A* dum() 
{ 
    A* a;    // The compiler reserves memory for holding 
         // the pointer a on the stack. 

    a = new A();  // On run time you reserve memory on the heap 
         // for holding an instance of class A. 

    doSomethingOnA(a); // Some function call where you pass the pointer 

    return a;   // Return the pointer. This will also release 
         // the stack memory used for holding the pointer a. 
} 

在另一功能:

void func() 
{ 
    A* b;    // The compiler reserves memory for holding 
         // the pointer b on the stack. 

    b = dum();   // The value of the pointer b is changed 
         // so it points to the instance of class A 
         // which is in the heap. The pointer b is 
         // still on the stack. 

    // ... more code 

    delete b;   // Delete b to free the heap memory 
         // (and call the class A destructor). 

    return;    // This will release 
         // the stack memory used for holding the pointer b. 
} 

你的第二示例

的原理是相同的。

和「無 - 你不需要新的功能達姆(..)內 事實上,這將是一個錯誤

bool dum(A* a) 
{ 
    // As this function has no local variable, no stack 
    // memory will be needed for holding variables. 

    // A* a = new A() -- Is this needed?  NO - it would be a bug 

    doSomethingOnA(a); 

    return 1; 
} 


void func() 
{ 
    A* b;    // The compiler reserves memory for holding 
         // the pointer b on the stack. 

    b = new A();  // On run time you reserve memory on the heap 
         // for holding an instance of class A. 
         // The value of the pointer b is changed 
         // so it points to the instance of class A 
         // which is in the heap. The pointer b is 
         // still on the stack. 

    dum(b);    // Just a function call 

    // ... more code 

    delete b;   // Delete b to free the heap memory 
         // (and call the class A destructor). 

    return;    // This will release 
         // the stack memory used for holding the pointer b. 
} 

注: 編譯器可以優化使用棧。因此,在函數內部的局部變量是在寄存器中完全保留,爲此並不需要在所有的內存。