2017-07-18 98 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; 
}