2010-05-26 73 views
8

我正在學習期末考試,偶然發現一個奇怪的問題,那是我們老師去年給一些可憐的靈魂考試的一部分。問題是這樣的:當使用malloc而不是new時,類成員會發生什麼?

以下程序是否正確或不正確?如果是,寫下程序輸出的內容。如果不是,請寫下原因。

程序:

#include<iostream.h> 
class cls 
{  int x; 
     public: cls() { x=23; } 
     int get_x(){ return x; } }; 
int main() 
{  cls *p1, *p2; 
     p1=new cls; 
     p2=(cls*)malloc(sizeof(cls)); 
     int x=p1->get_x()+p2->get_x(); 
     cout<<x; 
     return 0; 
} 

我的第一反應是與回答「程序是不正確的,因爲new應該用來代替malloc」。然而,在編譯程序並看到它輸出23我意識到那個答案可能不正確。

問題是我期待p2->get_x()返回一些任意數字(無論在調用malloc時發生在內存中的那一點)。然而,它返回0.我不確定這是否是巧合,或者當類成員是0時初始化爲malloc -ed。

  • 這種行爲(p2->x爲0後malloc)的默認值是?我應該有預計這個?
  • 你的回答我老師的問題是? (除了忘了#include <stdlib.h>malloc:P)
+4

爲什麼不能0也是一個任意數字? – 2010-05-26 15:14:59

+0

除了別的以外''應該只是''。 – 2010-05-26 15:16:30

+0

你也可以修復你的老師的內存泄漏。 – 2010-05-26 16:56:31

回答

14
  • 這是行爲(p2-> x在malloc後爲0)的默認值嗎?我應該預料到這一點嗎?

不,p2-> x在調用malloc之後可以是任何東西。它恰好在您的測試環境中爲0。

  • 你對我老師的問題的答案是什麼? (除了忘記#include for malloc:P)

大家都告訴過你,新結合了從freestore獲取內存和調用對象構造函數的調用。 Malloc只做了一半。

修復它:雖然示例程序是錯誤的。在類中使用「malloc」並不總是錯誤的。它是在你只需要就地調用添加到新的共享內存的情況完全有效:

p2=(cls*)malloc(sizeof(cls)); 
new(p2) cls; 
+2

如果您使用的是placement new,您還必須顯式調用析構函數(因爲您沒有使用new,所以不能使用delete)。你也應該明白,這是不常見的(當你爲多個項目預先分配存儲空間(不只是一個)時,用於構建自己的容器對象時使用main) – 2010-05-26 16:05:31

+1

我會爲使用'reinterpret_cast'而爭辯。它強調你正在做一件非常危險的事情。 – 2010-05-26 17:12:03

+0

爲了迴應Matthieu M.,我不想編輯5年前的問題,但是IMrecentE,我將上面的最後一個例子重寫爲void * p2Buffer = malloc(sizeof(cls)); cls * p2 = new(p2Buffer)cls ;.這樣你可以稍後調用p2->〜cls並釋放(p2Buffer);很明顯,p2是「類對象」,p2Buffer是分配的內存指針。 – jmucchiello 2015-06-28 06:36:00

3

新調用構造函數,malloc不會。所以你的對象將處於未知狀態。

+0

我知道'malloc'不會調用構造函數。我的問題是關於類成員'x' - 它是用0初始化還是獲得一些隨機值在內存中? – Felix 2010-05-26 15:14:01

+1

@Felix:如果構造函數未被調用,則成員數據的值是未定義的行爲。 – Cascabel 2010-05-26 15:15:06

+1

@Felix初始化x發生在構造函數中,所以它是未定義的。即使使用'new'也不會將x清零,除非在構造函數中x被設置爲0;成員字段不會像Java中的那樣獲得默認初始化 – 2010-05-26 15:15:42

1

實際的行爲是未知的,因爲new行爲非常相似,如malloc + constructor調用。

在你的代碼中,第二部分是丟失的,因此,它可以在一種情況下工作,但它不能,但你不能準確地說。

0

爲什麼不能0是任意數量呢?你在Debug模式下運行嗎?什麼編譯器?

VC++用一串0xCC字節值預先填充新分配的內存(在當然的調試模式下),所以如果您正在使用它,您將不會獲得答案的零。

+0

我使用g ++,沒有調試。 – Felix 2010-05-26 15:28:05

0

Malloc沒有保證將其分配的內存清零並且程序的結果是未定義的。

否則有很多其他的事情,使這個程序不正確的C + +。 cout在命名空間std,malloc需要包括通過#include <cstdlib>和iostream.h也不符合標準。

相關問題