Распределение членов класса в куче/стеке?

Если класс объявлен следующим образом:

class MyClass
{
  char * MyMember;
  MyClass()
  {
    MyMember = new char[250];
  }
  ~MyClass()
  {
    delete[] MyMember;
  }
};

А можно было бы сделать так:

class MyClass
{
  char MyMember[250];
};

Как класс выделяется в куче, например, если я делаю MyClass * Mine = new MyClass(); Выделяет ли выделенная память также 250 байтов во втором примере вместе с созданием экземпляра класса? И будет ли член действительным в течение всего времени существования объекта MyClass? Что касается первого примера, целесообразно ли размещать члены класса в куче?


person SimpleButPerfect    schedule 12.05.2010    source источник
comment
Возможный дубликат членов класса и явное выделение стека/кучи   -  person underscore_d    schedule 12.11.2017


Ответы (3)


Да, да и да.

Однако в вашем первом примере есть небольшая ошибка: поскольку один из его элементов данных является указателем с данными, выделенными в куче, он также должен объявить конструктор копирования и оператор присваивания, например, как . ..

MyClass(const MyClass& rhs) 
{
  MyMember = new char[250]; 
  memcpy(MyMember, rhs.MyMember, 250);
}
person ChrisW    schedule 12.05.2010
comment
Спасибо за подсказку, буду чаще использовать эту технику. - person SimpleButPerfect; 12.05.2010
comment
Хотя технически Крис прав, это не очень хорошая идея. Вместо этого используйте std::vector‹char›, и все ваше управление памятью будет обеспечено. Чтобы увидеть полную информацию: stackoverflow.com/questions/255612/ - person Martin York; 12.05.2010
comment
Вопрос был вовсе не о массивах, я должен был изменить этот пример, он касался самой концепции распределения. - person SimpleButPerfect; 13.05.2010

Раннее примечание: используйте std::string вместо выделенного в куче char[].

Выделяет ли выделенная память также 250 байтов во втором примере вместе с созданием экземпляра класса?

Он будет размещен в конструкторе в куче, так же, как в стеке, выделенном MyClass. Это зависит от того, что вы подразумеваете под «вместе с», это не обязательно будет выделено вместе.

И будет ли член действительным в течение всего времени существования объекта MyClass?

да.

Что касается первого примера, целесообразно ли размещать члены класса в куче?

Да, в определенных случаях. Иногда вы хотите свести к минимуму включения из файла заголовка, а иногда вы будете использовать фабричную функцию для создания члена. Однако обычно я просто использую простой элемент без указателя.

person Stephen    schedule 12.05.2010
comment
Спасибо за такой подробный ответ, что касается ранней заметки, я просто пытаюсь собрать знания по этому вопросу. - person SimpleButPerfect; 12.05.2010

Когда вы вызываете new, он выделяет из кучи, в противном случае он выделяет из стека (мы будем игнорировать malloc и ему подобные).

В вашем первом примере будет выделено место в обоих: 4 байта в стеке для экземпляра MyClass (при условии, что 32-битные указатели) и 250 байтов в куче для буфера, назначенного MyMember.

Во втором примере в стеке будет выделено 250 байт для экземпляра MyClass. В этом случае MyMember рассматривается как смещение в экземпляре.

person Anon    schedule 12.05.2010
comment
Это не совсем правильно, во втором примере класс содержит массив из 250 символов. все будет в куче, если вы сделаете что-то вроде MyClass *foo = new MyClass; - person Hasturkun; 12.05.2010
comment
Ах, я не видел new MyClass (или, возможно, ОП добавил его в правки, не указав временные рамки). Таким образом, этот ответ не совсем правильный, поскольку вопрос стоит. Но, к сожалению, я не могу удалить его. - person Anon; 12.05.2010