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

uninitialized_fill() - C++

Восстановить пароль Регистрация
 
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.09.2013, 10:55     uninitialized_fill() #1
Здорова!!!

Есть простая задачка: "Попробуйте переписать unitialized_fill() (параграф 19.4.4, параграф 3.1) так, что бы он справлялся с деструкторами, генерирующими исключения. Возможно ли это? Если да, то какова стоимость такого решения? Если нет, то почему?"

Ну что вы скажете, возможно ли такое???

Добавлено через 56 минут
Я от эти строчки кода не пойму
C++
1
2
3
4
5
int v1(5);
    int* p=new int;
    new (static_cast<void*>(&*p))int(v1);
    if(p!=0)
        cout <<"*p= "<<*p<<endl;
Что эта строчка означает new (static_cast<void*>(&*p))int(v1); ????

Добавлено через 1 минуту
Это что можно другими совами записать new void* int(v1) и что это будет?

Добавлено через 3 минуты
у нас получается указатель на войд по адрессу указателя p а затем идет int(v1) это можно сказать объект int , ну и как это понимать new void* 3 что ли как то так? Щас попробуем протестить.

Добавлено через 6 минут
От есть такой код работает:
C++
1
2
3
void* pp=new void*;
    new (pp)int(3);
    cout <<"*pp= "<<*(int*)(pp)<<endl;
А почему я не могу записать отак new(pp) 3;
что эта строчка означает я фиг пойму new (pp)int(3); ???? pp указывает на void* что это операция преобразования или что?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
castaway
Эксперт С++
4837 / 2976 / 367
Регистрация: 10.11.2010
Сообщений: 11,008
Записей в блоге: 10
Завершенные тесты: 1
26.09.2013, 11:59     uninitialized_fill() #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
struct A {
    A() {
        std::cout << "A::A()\n";
    }
};
 
int main() {
    ...
    A *p = new A;
    ...
    new (p) A; // память не выделяется, но вызывается конструктор объекта p
    ...
}
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.09.2013, 12:38  [ТС]     uninitialized_fill() #3
castaway, Ладно трудно это пока еще понять. Буду как синтаксис неосмысленный использовать.
А от смотри если у нас есть функция uninitialized_fill:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<class For, class T>
void uninitialized_fill(For beg, For end,  T& x)
{
    For p;
    try
    {
        for(p=beg;p!=end;++p)
            new (static_cast<void*>(&*p))T(x);//создаем копию х в *p (параграф 10.4.11)
        //&*p мы получаем адресс разыменованого элемента с целью получения указателя.
    }
    catch(...)
    {
        for(For q=beg;q!=p;++q)
        {
            (&*q)->~T();//вызываем деструктор
        }
        throw;
    }
}
Тут поддерживается базовая гарантия, та даже она не поддерживается потому что если в деструкторе будет сгернерировано исключение у нас произойдет утечка памяти, память просто высвободится в блоке и try и при исключении в catch будет удаляться с помощью деструктора, но когда деструктор вызовет какое нить исключение память не вся удалиться.

Я от придумал простое решение заключить снова в try блок и ловить исключения которые будут в деструкторе, так просто у нас получиться минимизировать утечку памяти, но полностью устранить на 100 % утечку не получить, потому что сам деструктор может сгенерировать исключение раньше чем он освободит память для объекта, мы тут сильную гарантию дать не можем, да какую сильную вообще базовую гарантию дать не можем????

Базовая гарантия это когда нет утечек ресурса и объект находится в состоянии нормальной инициализации, в коком нить состоянии, но может быть отличном от того до которого он был до выполнения операции.
Сильная гарантия это как базовая, только операция при неудаче не изменяет объект, он как и был остается в прежнем состоянии до выполнении операции
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
template<class For, class T>
void uninitialized_fill(For beg, For end,  T& x)
{
    For p;
    try
    {
        for(p=beg;p!=end;++p)
            new (static_cast<void*>(&*p))T(x);//создаем копию х в *p (параграф 10.4.11)
        //&*p мы получаем адрес разыменованого элемента с целью получения указателя.
    }
    catch(...)
    {
        for(For q=beg;q!=p;++q)
        {
            try
            {
                (&*q)->~T();//вызываем деструктор
            }
            catch(...)
            {
 
            }
        }
        throw;
    }
}
Добавлено через 6 минут
Ну допустим эту задачку я правильно сделал, просто методов вроде как других нету кроме как использовать try блок и при исключении возвращать объект в прежнее состояние, либо освобождать ресурсы. Но есть еще одна задачка которая более запутанная "Попробуйте переписать uninitialized_fill() (параграф 19.4.4, Е.3.1) так, что бы он справлялся с итераторами, которые генерируют исключения в операциях -- и ++. Возможно ли это? Если да, то какова стоимость такого решения? Если нет, то почему? " мне вообще не ясно где тут генерируется исключение что бы можно как небуть его переписать?

От код программки которую нужно переписать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<class For, class T>
void uninitialized_fill(For beg, For end,  T& x)
{
    For p;
    try
    {
        for(p=beg;p!=end;++p)
            new (static_cast<void*>(&*p))T(x);//создаем копию х в *p (параграф 10.4.11)
        //&*p мы получаем адресс разыменованого элемента с целью получения указателя.
    }
    catch(...)
    {
        for(For q=beg;q!=p;++q)
        {
            (&*q)->~T();//вызываем деструктор
        }
        throw;
    }
}
Добавлено через 6 минут
здесь похоже имеется введу что итератор сгенерирует исключение в этом блоке:
C++
1
2
3
4
5
6
7
8
catch(...)
    {
        for(For q=beg;q!=p;++q)
        {
            (&*q)->~T();//вызываем деструктор
        }
        throw;
    }
То такая запись даже не спасет:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
catch(...)
    {
        for(For q=beg;q!=p;++q)
        {
            try
            {
                (&*q)->~T();//вызываем деструктор
            }
            catch(...)
            {
 
            }
        }
        throw;
    }
Уже смысла нету оно будет просто зацикливание - крах программы. Значит получается тут уже нельзя ничего сделать. Получается для деструктора еще что то можно сделать, а от для операций итераторных ++ -- ничего не сделает, там 100% потеря ресурсов, но краха можно избежать.
castaway
Эксперт С++
4837 / 2976 / 367
Регистрация: 10.11.2010
Сообщений: 11,008
Записей в блоге: 10
Завершенные тесты: 1
26.09.2013, 13:21     uninitialized_fill() #4
Я вообще не понимаю, какое отношение unitialized_fill имеет к деструкторам?
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.09.2013, 13:38  [ТС]     uninitialized_fill() #5
Цитата Сообщение от castaway Посмотреть сообщение
Я вообще не понимаю, какое отношение unitialized_fill имеет к деструкторам?
она вызывает деструктор для того что бы высвободить память объекта. Да я щас токо смотрю по коду вроде объект влюбом случае портиться.
Да эта функция как бы сервисная для контейнеров, она вызывается в конструкторе вектор копирующем. ну или хз. Я сам щас запутался, щас буду еще разбираться.
castaway
Эксперт С++
4837 / 2976 / 367
Регистрация: 10.11.2010
Сообщений: 11,008
Записей в блоге: 10
Завершенные тесты: 1
26.09.2013, 13:41     uninitialized_fill() #6
Цитата Сообщение от ninja2 Посмотреть сообщение
она вызывает деструктор для того что бы высвободить память объекта.
Она не вызывает деструктор.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
26.09.2013, 13:50  [ТС]     uninitialized_fill() #7
Цитата Сообщение от castaway Посмотреть сообщение
Она не вызывает деструктор.
Деструктор вызывается в блоке catch(...) ( (&*q)->~T();//вызываем деструктор)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<class For, class T>
void uninitialized_fill(For beg, For end,  T& x)
{
    For p;
    try
    {
        for(p=beg;p!=end;++p)
            new (static_cast<void*>(&*p))T(x);//создаем копию х в *p (параграф 10.4.11)
        //&*p мы получаем адресс разыменованого элемента с целью получения указателя.
    }
    catch(...)
    {
        for(For q=beg;q!=p;++q)
        {
            (&*q)->~T();//вызываем деструктор
        }
        throw;
    }
}
Yandex
Объявления
26.09.2013, 13:50     uninitialized_fill()
Ответ Создать тему
Опции темы

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