声明指针时的隐式内存分配和初始化

时间:2012-12-12 03:00:57

标签: c++ pointers struct declaration allocation

  

可能重复:
  Declaring a pointer to struct in C++ automatically allocates memory for its members. Am I wrong?

假如我将结构Human定义为:

struct Human{int year, Human* Mom};

表达式

Human* Bob;

为Bob及其指向的Human对象自动分配内存? 因为我注意到了

Bob == NULL

是假的; 这是否意味着上面的表达式创建了对象Human的静态内存?

另外,我注意到了

Bob->year 

未自动初始化为0,但

Bob->Mom 

正被初始化为NULL,为什么会这样?

另一件事,如果我动态分配内存,例如

Human* Bob = new Human;

然后我找到了

Bob->Mom

不再是NULL,这是怎么回事?

5 个答案:

答案 0 :(得分:1)

至少应将结构声明更正为:

struct Human { int year; Human *Mom; };

声明:

Human *Bob;

然后创建一个存储位置,但如果在函数内创建它,则不会初始化它。如果它在全局范围内,它将被初始化为零(NULL),但是你说Bob == NULL是假的,所以它必须是一个未初始化的局部变量。它没有任何意义。除了作为赋值的目标之外,对它的任何使用都会调用未定义的行为,因为Bob中的值未定义。

没有;显示的定义不会为Bob分配存储空间来指向。

您的其他观察结果都取决于运行时系统的怪癖。因为行为是未定义的,所以任何事情都可能发生,根据标准,它是'OK'。您需要一个类型的默认构造函数,以便在使用时明智地设置值:

Human *Bob = new Human;

你没有提供一个,系统不需要提供一个,所以指向的对象是未初始化的。

答案 1 :(得分:0)

您有责任初始化指针值。除非您将它们设置为某些内容(例如0NULL),否则它们的值是未定义的,并且您可能会获得与每个相应分配不同的未初始化指针值。

在分配方面,您已定义了递归或自引用数据结构。考虑如果实际上确实为Mom成员为其他人分配了内存,会发生什么。然后它必须为Bob->Mom->Mom分配另一个人类......等等......

所以,不。只分配了一个Human。任何本机指针都只是一个内存地址位置,仅此而已。

如果使用构造函数,则可以更轻松地使指针初始化:

struct Human { 
    int year; 
    Human *Mom; 
    Human() : year(0), Mom(NULL) {}
};

答案 2 :(得分:0)

不,它不分配内存。 Bob是一个具有垃圾值的指针,所以谁知道它指向的是什么。

答案 3 :(得分:0)

  

表达Human * Bob;为Bob和它指向的Human对象自动分配内存?因为我注意到Bob == NULL是假的;这是否意味着上面的表达式创建了对象Human的静态内存?

不,它没有。鲍勃没有初始化,所以只会指向一些随机垃圾。您必须为Bob明确分配内存。

  

另一件事,如果我动态分配内存,例如人类*鲍勃=新人类;然后我发现Bob->妈妈不再是NULL,这是怎么回事?

如上所述,未初始化的内存中可能包含任何内容。试图按照指针将导致灾难。好的做法是将所有指针初始化为NULL或立即将它们指向已分配的内存块。

答案 4 :(得分:0)

在您的代码中,您给编译器的唯一指令是创建一个指针(32位或64位变量),您打算指向“Human”类型的结构。

由于您尚未初始化指针,因此其值很可能是该内存空间中的值 - 可能是0(NULL)或其他任何内容。

当您致电Bob-> Mom时,您正在取消引用指针(Bob)并查看内存中任意区域(可能是您不允许访问的空间)。您很可能会遇到分段错误(在* nix机器上)。

你应该做的是:

Human* Bob = new Human();

这将为结构创建专用空间并返回该结构的地址并将其分配给指针Bob。现在,当你取消引用Bob时,它实际上将指向一个专门为Human结构分配的空间。