2017-07-18 31 views
0

我想打印出值123456,但它給了我垃圾值。我該如何解決它?你能解釋爲什麼它給出了錯誤的價值嗎?C++,我怎麼得不到值「123456」

#include <stdio.h> 
#include <stdlib.h> 

struct MyInfo 
{ 
private: 
    int private_key = 123456; 
public: 
    int setkey(int value) 
    { 
     private_key = value; 
    } 
    int GetScore() 
    { 
     return private_key; 
    } 
}; 

void main() 
{ 
    MyInfo* pMyInfo; 
    pMyInfo = (MyInfo*)malloc(sizeof(MyInfo)); 

    printf("%d\n", pMyInfo->GetScore()); 

    free(pMyInfo); 
} 
+2

'malloc'只是返回原始內存。沒有任何物體會涌入那裏。 – StoryTeller

+0

構造函數添加到這個結構 'MyInfo的() \t { \t \t的std ::法院<< 「構造方法中調用」; \t}' with ** malloc **不調用構造函數,但** new **關鍵字可以寫** ** private_key的指定值** – Ibrahim

回答

4

不要使用malloc/free而是pMyInfo = new MyInfo()delete pMyInfo。只有new會調用初始化該值的構造函數;只有delete會調用析構函數。

關於評論,意思是說,你也可以把它放在棧上,即MyInfo pMyInfo;,即不是指針。這將自動調用構造函數以及何時超出作用域,析構函數。

+2

更好。不要使用原始動態分配和釋放。喜歡價值語義。 – StoryTeller

0

請勿混用CC++

你應該避免malloc/alloc等在C++,如果你想與動態分配對象的工作選擇new操作。

添加一個構造函數初始化值

private; 
    int private_key; 

public: 
    MyInfo() { 
     private_key = 123456; 
    } 

並實現主像

// without pointer 
void main() { 
    MyInfo myinfo; 
    printf("%d\n", myinfo.GetScore()); 
} 

// with pointer 
void main() { 
    MyInfo *myinfo = new MyInfo(); 
    printf("%d\n", myinfo->GetScore()); 
} 
+1

您添加的構造函數不會初始化它分配的值。 OP使用完全有效的C++ 11語法來初始化默認值。 – StoryTeller

+0

@StoryTeller我認爲它是4.3.2或4.9.9.3,因爲我從來沒有用過C++ 11 –

+0

N.P.我只是評論你如何才能改善答案。如果你讓構造函數實際初始化值,並擺脫泄漏,這個答案值得讚賞。 – StoryTeller

0

當您聲明型MyInfo的的指針,這並不意味着它指向將對象實際上是你的結構,它只是假設它會。

當你做malloc(sizeof(MyInfo)),你只需分配你的結構可能採取的大小的內存,它不會創建一個對象。因此,當您嘗試執行GetScore()時,它會訪問它假定包含您的private_key的內存位置,但它只是包含垃圾。

4
int private_key = 123456; 

這真的只是一個僞裝的構造函數初始化這意味着它是一樣的:

MyInfo() : private_key(123456) {} 

由於malloc和朋友都在C繼承和C無類(因此沒有特殊的成員函數)無論如何malloc和朋友不會調用這些必要的特殊成員函數來設置您的對象。然而,C++相當於new,這就是爲什麼您應該總是使用new而不是mallocdelete而不是free


別急,還有更精彩的......

其實,你不應該永遠使用new要麼,有總是比使用原始動態分配更好的選擇。如果你真的需要動態內存分配,然後使用std::unique_ptr或多個對象std::vector但大多數時候你甚至不需要這些(這裏有大量的帖子解釋何時動態分配是必須的,對於所有其他情況使用自動存儲壽命)你在這種情況下,需要的是一個本地對象:

MyInfo myInfo; 
printf("%d\n", myInfo.GetScore()); 

見你的代碼是如何獲得更短,更易於維護和清潔劑來達到同樣的?

0

僅供參考,可以在原始存儲中初始化一個對象,但對於此用例來說,這將是矯枉過正而相當愚蠢的做法。作爲唯一的malloc分配原始內存,並且不構造一個對象,你可以使用新的放置建對象第二次:

int main()  // I can't stand void main 
{ 
    MyInfo* pMyInfo; 
    pMyInfo = (MyInfo*)malloc(sizeof(MyInfo)); // only allocate raw memory 
    new((void *) pMyInfo) MyInfo;    // construct the object 

    std::cout << pMyInfo->GetScore() << std::endl; // no reason for C printf here 

    pMyInfo->~MyInfo(); // placement new requires explicit destructor call if not trivial 
    free(pMyInfo); 
    return 0; 
} 

不這樣做,這樣一個簡單的例子。只有在分配不重要的非常特殊的情況下,例如當您使用共享內存時,才應使用新增功能。但這裏正確的方法是簡單地使用自動對象:

int main()  // I can't stand void main 
{ 
    MyInfo pMyInfo; 

    std::cout << pMyInfo.GetScore() << std::endl; 

    return 0; 
} 
相關問題