2010-05-26 88 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也不符合标准。

相关问题