Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > new : пара вопросов по терминологии


Автор: FCM 14.9.2009, 10:15
1) Почему в MSVC new(std:: nothrow) называют placement? Он же за исключением "негенерации исключений" не отличается от обычного new, который там же называют noplacement.
В то же время не выделяющий памяти "размещающий" new(), который существенно отличается от обоих вышеприведенных, тоже называют plаcement. Что подразумевается под placement если не размещающий? 

2) Вот пример из Help MSVC
Код

#include <stdio.h>
#include <new.h>
int main() {
   int * i = new int(12);
   printf("*i = %d\n", *i);
   // initialize existing memory (i) with, in this case, int(7)
   int * j = new(i) int(7);   // placement new
   printf("*j = %d\n", *j);
   printf("*i = %d\n", *i);
   delete i;   // or, could have deleted j
}


По сути память была инициализирована в первой инструкции главной функции. Однако о размещении в ней значения 7, в комментариях говорится как о (повторной) инициализации. В чем тут фишка? В том, что размещающая форма new в общем случае может разместить туда значение другого типа, что является "переинициализацией" памяти?

Автор: zim22 14.9.2009, 10:25
Цитата(FCM @  14.9.2009,  10:15 Найти цитируемый пост)
. В чем тут фишка?

обычный оператор new выделяет память под объект из free store. адрес памяти будет любой.
например
Код

int *p = new int(10); // p будет указывать на любой адрес, типа 0x00251e08


но placement new позволяет разместить объект в заранее определённом месте
например
Код

int *ptr = reinterpret_cast<int*>(0xFFFFFFFF);
int *zzz = new(ptr) int(99); // объект будет размещён по адресу 0xFFFFFFFF)

или сюда:
Код

char buf[256];
int *ptr = new (buf) int(66);

Автор: Lazin 14.9.2009, 10:33
Цитата(FCM @  14.9.2009,  10:15 Найти цитируемый пост)
1) Почему в MSVC new(std:: nothrow) называют placement? 

new(nothrow) не называют placement, вы что-то путаете

Автор: FCM 14.9.2009, 14:39
Цитата(Lazin @  14.9.2009,  10:33 Найти цитируемый пост)
new(nothrow) не называют placement, вы что-то путаете 


Тогда может я чего то неправильно понимаю из следующей выдержки из Help MSVC

Allocates block of memory from heap

 
Код

void *__cdecl operator new(
   size_t count
);
void *__cdecl operator new(
   size_t count, 
   void * object
) throw();
void *__cdecl operator new(
   size_t count, 
   const std::nothrow_t&
) throw();

 

Remarks
This form of operator new is known as scalar new, in contrast to the vector new form (operator new[]).

The first form of this operator is known as the nonplacement form. The second form of this operator is known as the placement form and the third form of this operator is the nonthrowing, placement form.

The first form of the operator is defined by the compiler and does not require new.h to be included in your program.


Автор: Lazin 14.9.2009, 15:46
попробую объяснить доступно
оператор new может бросать исключение типа bad_alloc, nothrow и placement не бросают это исключение, nothrow версия new - возвращает 0, placement не выделяет память, поэтому то-же не может
nothrow placement, это нонсенс, невозможное и бессмысленное сочетание smile

Добавлено через 7 минут и 12 секунд
Цитата(http://cplusplus.com/reference/std/new/operator%20new/)

Код

void* operator new (std::size_t size) throw (std::bad_alloc);
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
void* operator new (std::size_t size, void* ptr) throw();


Allocate storage space

The first version allocates size bytes of storage space, aligned to represent an object of that size, and returns a non-null pointer to the first byte of this block. On failure, it throws a bad_alloc exception.

The second version is the nothrow version. It does the same as the first version, except that on failure it returns a null pointer instead of throwing an exception.

The third version is the placement version, that does not allocate memory - it simply returns ptr. Notice though that the constructor for the object (if any) will still be called by the operator expression.

Автор: FCM 14.9.2009, 17:13
Ну значит имеют место быть "неточности" в приведенном ранее фрагменте документации MSVC (7,9) или они вкладывают свой "смысл" в placement.

Автор: Lazin 31.10.2009, 15:03
Цитата(FCM @  14.9.2009,  10:15 Найти цитируемый пост)
1) Почему в MSVC new(std:: nothrow) называют placement? Он же за исключением "негенерации исключений" не отличается от обычного new, который там же называют noplacement.
В то же время не выделяющий памяти "размещающий" new(), который существенно отличается от обоих вышеприведенных, тоже называют plаcement. Что подразумевается под placement если не размещающий?

действительно, nothrow версию new то-же называют placement
правда, по какой причине, я не знаю, видимо они placement, потому, что используются явно, вместо обычного new, замещают его

Цитата(FCM @  14.9.2009,  17:13 Найти цитируемый пост)
Ну значит имеют место быть "неточности" в приведенном ранее фрагменте документации MSVC (7,9) или они вкладывают свой "смысл" в placement.
 smile 

Автор: UnrealMan 31.10.2009, 16:57
Цитата(Lazin @  31.10.2009,  15:03 Найти цитируемый пост)
правда, по какой причине, я не знаю, видимо они placement, потому, что используются явно, вместо обычного new, замещают его

Цитата
new-expression:
    ::opt new new-placement opt new-type-id new-initializer opt
    ::opt new new-placement opt ( type-id ) new-initializer opt

new-placement:
    ( expression-list )

Из описания синтаксиса видно, что new-placement может использоваться, а может не использоваться. Если new-placement используется, то в функцию operator new передаются дополнительные аргументы, указанные в expression-list. Соответственно, все функции operator new, которые могут принимать дополнительные аргументы (в добавок к первому типа size_t), называются placement allocation function. Если new-expression не смогло создать объект из-за того, что конструктор объекта выкинул исключение, то при наличии placement deallocation function (operator delete то бишь), список дополнительных параметров которой в точности совпадает с оным у заюзаной placement allocation function, эта deallocation function будет вызвана с теми же дополнительными аргументами, чтобы освободить выделенную память (если такой соответствующей operator delete нету, то будет утечка памяти).

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)