Форум программистов, компьютерный форум CyberForum.ru

Как работает "new с размещением" - C++

Восстановить пароль Регистрация
 
dalay_lama
 Аватар для dalay_lama
65 / 65 / 7
Регистрация: 22.09.2012
Сообщений: 434
19.07.2014, 10:40     Как работает "new с размещением" #1
Всем доброго времени суток. Уважаемые знатоки, объясните пожалуйста, как работает "new с размещением"? Сейчас занимаюсь по книге С. Прата, дошёл до этой темы, но всё равно никак не могу уловить, как например срабатывает такое:
C++
1
2
char buff[512];
double *p = new (buff) double[5]
Это же разные типы? Почему такое возможно?
Как я сейчас на данный момент понимаю, что происходит: в участок памяти, в котором находится переменная buff, помещается 5 значений типа double. Соответственно мы заняли 48 байт из 512. Я это правильно понимаю? если да, то это ещё как-то у уменя в голове укладывается. Но тогда вопрос в следующем, а что будет, если я в этот буффер, положу значение, которое больше чем сам буффер? например:
C++
1
2
char buff[512];
double *p = new (buff) double[100];
И вообще, для чего может потребоваться такая операция? я имею введу new с размещением
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
dimabubyakin
 Аватар для dimabubyakin
158 / 123 / 44
Регистрация: 16.10.2013
Сообщений: 1,732
Завершенные тесты: 5
19.07.2014, 11:05     Как работает "new с размещением" #2
Скомпилируй данный код, и посмотри на примере как работает это)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#define n 128
#define m 24
using namespace std;
int main()
{
 
    int buf[n];
    int *p = new(buf) int[m];
 
    for(int i=0;i<n;i++)
        {
            buf[i]=0;
            cout<<buf[i];
        }
 
    cout<<endl<<"New:"<<endl;
 
    for(int i=0;i<m;i++)
        p[i]=1;
 
    for(int i=0;i<n;i++)
        cout<<buf[i];
 
 
    cout<<endl;
    system("pause");
    return 0;
}
Добавлено через 4 минуты
Не сталкивался с таким, сейчас по твоему коду просто пример написал, так легче понять( по крайней мере для меня) так вот, не уверен в правильности того что напишу, это мое мнение, но мы просто выделяем память уже выделенного блока)
NEbO
583 / 451 / 49
Регистрация: 22.01.2009
Сообщений: 1,173
Записей в блоге: 1
Завершенные тесты: 1
19.07.2014, 11:08     Как работает "new с размещением" #3
dalay_lama, подскажите, пожалуйста, название и версию компилятора, под которым можно скомпилить это дело.
dimabubyakin
 Аватар для dimabubyakin
158 / 123 / 44
Регистрация: 16.10.2013
Сообщений: 1,732
Завершенные тесты: 5
19.07.2014, 11:10     Как работает "new с размещением" #4
к примеру массив a[10] => 1111111111
выделяем эту память под массив b[5] и заполним его нулями
выведем массив a[10] получим 0000011111

Добавлено через 20 секунд
NEbO, я в devcpp 4.9 запускал)
NEbO
583 / 451 / 49
Регистрация: 22.01.2009
Сообщений: 1,173
Записей в блоге: 1
Завершенные тесты: 1
19.07.2014, 11:18     Как работает "new с размещением" #5
Цитата Сообщение от dimabubyakin Посмотреть сообщение
devcpp 4.9
там вроде gcc должен быть, но какой версии?
пробовал скомпилить вот такое:
C++
1
2
3
4
5
int main() {
    char buf[512];
    int *p = new (buf) int[5];
    return 0;
}
в том числе с -std=c++14, и без него. также пробовал на http://gcc.godbolt.org/ компиляторами icc, gcc, clang.
все утверждают одно, что нет такой перегруженной функци для оператора new:
Код
tst.cpp: В функции «int main()»:
tst.cpp:3:26: ошибка: нет соответствующей функции для вызова «operator new [](sizetype, char [512])»
  int *p = new (buf) int[5];
                          ^
tst.cpp:3:26: замечание: candidate is:
<built-in>: замечание: void* operator new [](unsigned int)
<built-in>: замечание:   candidate expects 1 argument, 2 provided
dimabubyakin
 Аватар для dimabubyakin
158 / 123 / 44
Регистрация: 16.10.2013
Сообщений: 1,732
Завершенные тесты: 5
19.07.2014, 11:21     Как работает "new с размещением" #6
Поставил n 20, а m 15, вывод таков
Код
11111111111111111111
New:
00000000000000011111
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,048
19.07.2014, 11:22     Как работает "new с размещением" #7
Цитата Сообщение от dalay_lama Посмотреть сообщение
Соответственно мы заняли 48 байт из 512.
почему 48???
размер double 8 байт 8*5=40
Цитата Сообщение от dalay_lama Посмотреть сообщение
Уважаемые знатоки, объясните пожалуйста, как работает "new с размещением"?
если ты это имеешь ввиду Placement new
то почитай
http://ru.wikipedia.org/wiki/New_(C%2B%2B)
соответствующую главу
в двух словах
Цитата Сообщение от dalay_lama Посмотреть сообщение
char buff[512];
здесь мы выделили память под 512 байт
почему char? Потому что в Си char равен одному байту
Цитата Сообщение от dalay_lama Посмотреть сообщение
double *p = new (buff) double[5]
здесь в выделенной памяти создали пять объектов double
причем new в такой конструкции не выделяет память, она уже выделена, а вызывает конструктор, в данном случае double
Цитата Сообщение от dalay_lama Посмотреть сообщение
И вообще, для чего может потребоваться такая операция?
когда у тебя уже есть выделенный участок памяти и тебе нужно положить туда определенный тип, например свой класс
Часто такой метод применяют, когда у класса нет конструктора по умолчанию и при этом нужно создать массив объектов.
Цитата Сообщение от dalay_lama Посмотреть сообщение
Но тогда вопрос в следующем, а что будет, если я в этот буффер, положу значение, которое больше чем сам буффер?
А рухнет все А может не рухнет неизвестно к чему приведет
выходим за границы памяти
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
19.07.2014, 11:23     Как работает "new с размещением" #8
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от NEbO Посмотреть сообщение
нет такой перегруженной функци для оператора new:
C++
1
#include <new>
Цитата Сообщение от dalay_lama Посмотреть сообщение
Это же разные типы? Почему такое возможно?
Потому что принимается void*, которому можно указатель на любой тип.
Цитата Сообщение от dalay_lama Посмотреть сообщение
в участок памяти, в котором находится переменная buff, помещается 5 значений типа double.
Правильно.
Цитата Сообщение от dalay_lama Посмотреть сообщение
положу значение, которое больше чем сам буффер?
UB. Это тоже самое, что писать больше байт, чем выделено и при обычном случае (new или просто массив на стеке).
Цитата Сообщение от dalay_lama Посмотреть сообщение
для чего может потребоваться такая операция?
Обычно для реализации своих менеджеров памяти.
dalay_lama
 Аватар для dalay_lama
65 / 65 / 7
Регистрация: 22.09.2012
Сообщений: 434
19.07.2014, 11:53  [ТС]     Как работает "new с размещением" #9
Цитата Сообщение от NEbO Посмотреть сообщение
подскажите, пожалуйста, название и версию компилятора, под которым можно скомпилить это дело.
gcc. Не забудьте добавить #include <new>

Цитата Сообщение от ValeryS Посмотреть сообщение
почему 48???
ох, простите, это я позабыл таблицу умножения

Цитата Сообщение от ValeryS Посмотреть сообщение
почему char? Потому что в Си char равен одному байту
Да я знаю сколько char занимает) я имел введу как так получается, что в место, где хранится char, мы ложим double, но уважаемый Tulosba, уже мне разъяснил этот момент)

Tulosba и ValeryS - огромное вам спасибо, всё стало на свои места, низкий вам поклон)
NEbO
19.07.2014, 12:20
  #10

Не по теме:

Цитата Сообщение от Tulosba Посмотреть сообщение
#include <new>
мда, видимо сегодня у меня будет очень удачный день...

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.07.2014, 12:20     Как работает "new с размещением"
Еще ссылки по теме:

C++ Как отключить автоматическое добавление "_" "@" "number" к имени экстернального метода?
Патерн "прототип" не работает, выдаёт ошибку "недопустимый вызов нестатической ф-ции", где я в коде ошибка? C++
C++ Почему не работает "system("pause")"?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
19.07.2014, 12:20     Как работает "new с размещением" #11
Цитата Сообщение от porshe Посмотреть сообщение
можно ли использовать эту конструкцию( new с размещением ) вместо функции realloc() из cstdlib?
Вместо realloc лучше подошел бы std::vector. А размещающий вариант new вообще не выделяет память, так что предлагать его на замену realloc довольно странно.
Yandex
Объявления
19.07.2014, 12:20     Как работает "new с размещением"
Ответ Создать тему
Опции темы

Текущее время: 00:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru