Когда выделяется память с использованием alloca для членов класса? - PullRequest
3 голосов
/ 02 ноября 2011
class MyString
{
  public:
  MyString(int length):_ptr(alloca(length))
  {
  }
  //Copy Constructor, destructor, other member functions.
  private:
  void* _ptr;
};

int main()
{
  MyString str(44);
  return 0;
}

Освобождается ли он в конце основной функции или сразу после выполнения конструктора?Является ли хорошей идеей иметь строковый класс, подобный этому, если приведенный выше код работает должным образом?

Обновление:

Похоже, что главная опасность

  1. StackOverflow
  2. Встраивание конструктора

Я думаю, что я могу позаботиться о StackOverflow, используя alloca для небольших размеров и malloc / free для больших размеров.Я предполагаю, что должен быть какой-то непереносимый способ компилятора встроить компилятор.

Мне интересно, потому что строковый класс - это то, что широко используется в любом проекте c ++.Если я пойму это правильно, я ожидаю огромного прироста производительности, так как большая часть выделений идет в стек, который в противном случае попадет в кучу.Это будет утилита, и конечный пользователь не будет знать о внутренностях.

Ответы [ 2 ]

5 голосов
/ 02 ноября 2011

Согласно документации на alloca память освобождается при возврате вызывающего объекта alloca.Таким образом, память будет освобождена в конце конструктора, если список инициализатора рассматривается компилятором как часть конструктора, то есть кадр стека создается до выполнения списка инициализации.Если кадр стека создается после выполнения списка инициализатора, то выделенная память будет в вызывающей стороне конструктора и, таким образом, в этом случае память освобождается в конце main.Я не знаю стандарта достаточно, чтобы быть абсолютно уверенным, каким образом это произойдет.

Однако значение ptr не изменится, когда память будет окончательно освобождена.

3 голосов
/ 02 ноября 2011

Определенно, инициализация членов класса выполняется как часть c'tor.Так что, по крайней мере, по стандарту, валидность указателя, возвращаемого alloca, ограничена c'tor.

Так что кажется очень плохой идеей инициализировать членов вашего класса так, как вы делаете.

OTOH не будет проблем со следующим:

class MyString
{
  public:
  MyString(void* ptr):_ptr(ptr)
  {
  }
  //Copy Constructor, destructor, other member functions.
  private:
  void* _ptr;
};

int main()
{
  MyString str(alloca(44));
  return 0;
}
...