Что происходит с учениками, когда вместо нового используется malloc? - PullRequest
8 голосов
/ 26 мая 2010

Я готовлюсь к выпускному экзамену и наткнулся на любопытный вопрос, который был частью экзамена, который наш учитель дал в прошлом году некоторым бедным душам. Вопрос звучит примерно так:

Правильна ли следующая программа или нет? Если это так, запишите, что выводит программа. Если это не так, запишите почему.

Программа:

#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;
}

Моим первым инстинктом было ответить «программа неверна, так как вместо malloc следует использовать new». Однако после компиляции программы и просмотра ее вывода 23 я понимаю, что этот ответ может быть неправильным.

Проблема в том, что я ожидал, что p2->get_x() вернет какое-то произвольное число (что бы ни находилось в этом месте памяти при вызове malloc). Тем не менее, он вернул 0. Я не уверен, является ли это совпадением или члены класса инициализируются с 0, когда он malloc -ед.

  • Является ли это поведение (p2->x равным 0 после malloc) по умолчанию? Должен ли я ожидается это?
  • Каким будет ваш ответ на вопрос моего учителя? (кроме забыть #include <stdlib.h> для malloc: P)

Ответы [ 5 ]

14 голосов
/ 26 мая 2010
  • Является ли это поведение (p2-> x равным 0 после malloc) по умолчанию? Должен ли я этого ожидать?

Нет, p2-> x может быть любым после вызова malloc. В вашей тестовой среде это просто 0.

  • Как бы вы ответили на вопрос моего учителя? (кроме того, что забыли #include для malloc: P)

То, что вам сказали все, new сочетает в себе вызов для получения памяти из freestore и вызов конструктора объекта. Маллок делает только половину этого.

Исправление: пока пример программы неверен. Не всегда неправильно использовать «malloc» с классами. Это совершенно справедливо в ситуации с общей памятью, вам просто нужно добавить вызов на месте к новому:

p2=(cls*)malloc(sizeof(cls));
new(p2) cls;
3 голосов
/ 26 мая 2010

new вызывает конструктор, malloc не будет. Таким образом, ваш объект будет в неизвестном состоянии.

1 голос
/ 26 мая 2010

Реальное поведение неизвестно, потому что new действует почти так же, как malloc + constructor call.

В вашем коде вторая часть отсутствует, следовательно, она может работать в одном случае, не может, но вы не можете сказать точно.

0 голосов
/ 26 мая 2010

Malloc не дает гарантии обнуления памяти, которую он выделил, и результат программы не определен.

В противном случае есть много других вещей, которые мешают этой программе быть корректной C ++. cout находится в пространстве имен std, malloc необходимо включить через #include <cstdlib> и iostream.h также не соответствует стандарту.

0 голосов
/ 26 мая 2010

Почему 0 тоже не может быть произвольным числом? Вы работаете в режиме отладки? Какой компилятор?

VC ++ предварительно заполняет вновь выделенную память строкой байтовых значений 0xCC (конечно, в режиме отладки), чтобы вы не получили ноль за ответ, если бы использовали его.

...