2013-07-14 8 views
7

Мне известно, что вызов delete для переменной, созданной с использованием места размещения new, а затем доступа к этому блоку памяти имеет неопределенное поведение.Удалить при размещении new

int* x = new int[2]; 
char* ch = new(x) char(); 
*ch = 't'; 
delete ch; 

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

int x[2]; 
char* ch = new(x) char(); 
*ch = 't'; 
delete ch; 

Так список вопросов:

  • исключение связи с призывом удалить в стеке?
  • Можно ли использовать новое размещение на блоке памяти в стеке?
  • Если да, то как мне удалить указатель на символ.
  • Можно ли назначить несколько переменных в одном блоке памяти с использованием места размещения new?
+1

http://www.parashift.com/c++-faq/placement-new.html – Drax

ответ

16

Является ли исключение из-за вызова удаления в стеке?

Да. Хотя немного разъяснить, это не исключение C++. Это ошибка, обнаруженная во время выполнения. Если время выполнения не настолько умное, вы также можете столкнуться с неопределенным поведением.

Возможно ли использовать новое место на блоке памяти на стеке?

Да. Вы также можете взглянуть на alloca() и Variable-length arrays (VLA) - это еще два механизма выделения памяти в стеке. Обратите внимание, что VLA является частью стандартов C99, а не C++ 11 (и более ранних), но поддерживается большинством компиляторов производственного уровня в качестве расширения (он может появиться в C++ 14).

Если да, то как я должен удалить указатель на символ.

Вы не должны. Когда вы используете новое место размещения, вы не вызываете delete, вы просто вызываете деструктор. Для любого объекта o типа T необходимо позвонить по телефону o->~T(); вместо delete o;. Однако, если вы должны иметь дело с кодом, который вызывает delete или delete [] на таком объекте, вам может потребоваться перегрузить операторы delete и delete[] и заставить эти операторы ничего не делать (деструктор уже запущен в этой точке).

Можно ли назначить несколько переменных в одном блоке памяти с помощью размещения new?

Да. Однако вам необходимо проявлять особую осторожность, чтобы убедиться, что вы встретите alignment requirements.

+0

Отличный ответ. а всего лишь 1 разъяснение.при использовании нового места размещения в стеке, выделенная память начинается с начала, а затем перемещается вперед или случайным образом распределяет память в данном блоке. кажется, что первый вариант правильный. исправьте меня, если я ошибаюсь – Saksham

+0

@Saksham: Размещение new не выделяет никакой памяти вообще. Он использует память, указанную в качестве аргумента. Что касается выделения памяти в стеке - это зависит от архитектуры, она может расти вовнутрь или наружу. Однако любой отдельный объект в стеке будет иметь свой базовый адрес ниже, поэтому, если вы хотите разместить несколько объектов с помощью 'placement new []', выделите для них память сразу. –

+0

Мой плохой неверный язык для «выделенной памяти». это должно было быть «использовано в памяти» – Saksham

Смежные вопросы