powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Поймать факт перезаписи
123 сообщений из 123, показаны все 5 страниц
Поймать факт перезаписи
    #38073764
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
struct catcher
{ 
    // то тут?
};
catcher* globalStore = 0;
int main()
{
    globalStore = new catcher;
    globalStore = new catcher; // как автоматом удалить первый
    
    return 0;
}



Можно ли как-нибудь в кетчере поймать факт перезаписи указателя и соотв. автоматом убить первый объект??
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074263
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кажется в общем случае эта проблема называется Memory Leak Detection
и можно искать по этим ключевым словам.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074285
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixМожно ли как-нибудь в кетчере поймать факт перезаписи указателя и соотв. автоматом убить первый объект??
Да. Использовать смарт указатели.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074287
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть разные способы борьбы с проблемой. На мой взгляд для С++ надо просто не писать
такой код. Попытка создать сверх-умные указатели привела к созданию целого спектра
тяжёлых технологий которые сегодня юзаются в Java и .Net. Это не путь С++. Короче
Это не путь для истинного "самурая".
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074294
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Правильно, надо использовать достаточно умные указатели, а не слишком умные :)
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074295
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну он не истинный самурай - переживет.
Но вот то, что он хочет именно в исходно запрошенном виде - это действительно не С++ ))
А умные поинтеры - почему бы и нет?
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074298
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну.. щас мы с вами разбежимся в разные стороны. А какие умные?
auto_ptr? shared_ptr? Каких библиотек? И вообще какие умнее?
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074323
Фотография kosh the best
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
можете попробовать перегрузить new для catcher..
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074328
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton ,
Либо я чего-то не понял, либо вопрос должен звучать не так:

А какие умные? И вообще какие умнее?

А так:

А какие решают поставленную задачу?


Выглядит как "Ща мы разбежимся, а чтобы мотивировать вас, я тут припас... дробовик!"
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074334
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дада. И дробовик у меня тоже есть. Давайте в контексте.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074350
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что давать то?
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074364
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дискутировать говорю в контексте вопроса.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074372
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В контексте вопроса "Какие указатели умнее?" или в контексте вопроса "Как автоматически удалить объект?"? Хватит флиртовать, не пятница же.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074399
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А шо тут дискутировать.
OoCc уже ответил - использовать смарт-указатели.
Если указатели только локальные, то - std::auto_ptr, std::unique_ptr, boost::scoped_ptr.
Если плнируется передавать за пределы функции - то std::shared_ptr, boost::shared_ptr.
Выбрать из списка то что поддерживает компилятор.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074514
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
auto_ptr вроде как deprecated теперь... вместо него (если нужно именно его поведение) предлагают std::unique_ptr
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074516
Фотография kosh the best
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну видно же, что автор топика хочет "прострелить себе ногу", фигурально выражаясь
поэтому, несомненно, настойчиво рекомендую перегрузить ему оператор new
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074549
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kosh the bestну видно же, что автор топика хочет "прострелить себе ногу", фигурально выражаясь
поэтому, несомненно, настойчиво рекомендую перегрузить ему оператор new
Код давайте. Это будет уже интересный вброс для обсуждения и более чем в контексте ))
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074564
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edd.Dragonkosh the bestну видно же, что автор топика хочет "прострелить себе ногу", фигурально выражаясь
поэтому, несомненно, настойчиво рекомендую перегрузить ему оператор new
Код давайте. Это будет уже интересный вброс для обсуждения и более чем в контексте ))

из статического массива сделать фабрику указателей - банально.
Давайте сразу что нибудь с векторами унутрях )
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074581
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЕсть разные способы борьбы с проблемой. На мой взгляд для С++ надо просто не писать
такой код. Попытка создать сверх-умные указатели привела к созданию целого спектра
тяжёлых технологий которые сегодня юзаются в Java и .Net. Это не путь С++. Короче
Это не путь для истинного "самурая".

Ошибаешься, там не смартуказатели, там габаж колекторы.
Габаж коллекторы медленные. Смартуказатели быстрые.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074643
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivmaytonЕсть разные способы борьбы с проблемой. На мой взгляд для С++ надо просто не писать
такой код. Попытка создать сверх-умные указатели привела к созданию целого спектра
тяжёлых технологий которые сегодня юзаются в Java и .Net. Это не путь С++. Короче
Это не путь для истинного "самурая".

Ошибаешься, там не смартуказатели, там габаж колекторы.
Габаж коллекторы медленные. Смартуказатели быстрые.

А принцип С++ "Определение - есть инициализация " (С) Страуструп ,
еще быстрее :)
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074646
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаР
А принцип С++ "Определение - есть инициализация " (С) Страуструп ,
еще быстрее :)

Поэтому я поддерживаю идею повелосипедить на предмет перегрузки для придания умности new.
И сравнить производительность.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074685
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Другое дело.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074689
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kosh the bestможете попробовать перегрузить new для catcher..

Можете подсказать как именно построить решение с перегрузкой new / delete конкретно для этого случая?


Код: plaintext
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.
struct catcher
{ 
    public:
    void* operator new(size_t size) 
    { 
        // как тут получить доступ к перезаписываемому
        // указателю-то??

        return ::operator new(size, std::nothrow); 
    }
    void operator delete(void* obj) 
    { 
        ::operator delete(obj); 
        
        // через что тут обнулять-то??
        // ведь операция удаления в самом
        // общем виде не обязывает программу
        // юзать указатель вообще...
    }
    
};
catcher* globalStore = 0;
int main()
{
    globalStore = new catcher;
    globalStore = new catcher;
    
    return 0;
}
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074714
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivmaytonЕсть разные способы борьбы с проблемой. На мой взгляд для С++ надо просто не писать
такой код. Попытка создать сверх-умные указатели привела к созданию целого спектра
тяжёлых технологий которые сегодня юзаются в Java и .Net. Это не путь С++. Короче
Это не путь для истинного "самурая".

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

Кстати в тему продолжения 13587263 . Я ставил Oracle JRockit
чтобы посмотреть как ораклоиды хвастаются своим новым GC. Но пока
еще до тестов дело не дошло.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074735
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixkosh the bestможете попробовать перегрузить new для catcher..

Можете подсказать как именно построить решение с перегрузкой new / delete конкретно для этого случая?


Код: plaintext
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.
struct catcher
{ 
    public:
    void* operator new(size_t size) 
    { 
        // как тут получить доступ к перезаписываемому
        // указателю-то??

        return ::operator new(size, std::nothrow); 
    }
    void operator delete(void* obj) 
    { 
        ::operator delete(obj); 
        
        // через что тут обнулять-то??
        // ведь операция удаления в самом
        // общем виде не обязывает программу
        // юзать указатель вообще...
    }
    
};
catcher* globalStore = 0;
int main()
{
    globalStore = new catcher;
    globalStore = new catcher;
    
    return 0;
}



Обьявите статическую переменную в struct catcher в которой храните адрес globalStore который вернул
первый вызов new.
При повтороном вызове new память не выделяете , бросаете исключение , или возвращаете
адрес существующего обьекта из статической переменной.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074760
stepplerus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ДохтаР,

"А ларчик просто открывался" (С)

А то - суперуказатели, шарепоинтеры... тьфу!
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074767
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stepplerusДохтаР,

"А ларчик просто открывался" (С)

А то - суперуказатели, шарепоинтеры... тьфу!


В данном случае с ГлобалСторе, да.
А если обьъектов данного типа в программе будет овер 9000 ,
то без вумных указателей задача не такая тривиальная.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074780
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запретите себе прямую работу с указателями. Сделайте set/get функции для этих указателей. Просто и легко, но требует дисциплины.
Либо изучайте smart pointers + garbage collection.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074787
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаРОбьявите статическую переменную в struct catcher в которой храните адрес globalStore который вернул
первый вызов new.


компилятор пишет, что войдовые дата-мемберы запрещены стандартом и соотв. про нижние 3 строчки пишет, что переменная автокилл не определена. других ошибок не найдено. как быть??

Код: plaintext
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.
class catcher
{ 
    public:
    static void* autoKill = 0;
    void* operator new(size_t size) 
    { 
        if (autoKill) ::operator delete(autoKill);
        autoKill = ::operator new this;
        return autoKill;
    }
    
};
class user : public catcher
{ 
    public: 
    int a;
    user(int p) { a = p; } 
};
user* globalStore = 0;
int main()
{
    globalStore = new user(5);
    globalStore = new user(6);
    
    return 0;
}
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074803
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix, ты лучше не словами. А копи-пасти выхлоп компиллятора. Те кому надо - разберуться.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074815
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonLumix, ты лучше не словами. А копи-пасти выхлоп компиллятора. Те кому надо - разберуться.

Я конечно могу, но я думал на этом форуме кидать дамп это моветон...

Там реально ISO forbid void* data member. и больше ничего интересного
а кроме того, приведенный пример является полным, то есть это не кусок из рабочего когда, весь *.cpp файл целиком. Каждый может вырезать его, вставить в пустой файл, скомпилить G++ ом и все увидеть самому.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074846
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixДохтаРОбьявите статическую переменную в struct catcher в которой храните адрес globalStore который вернул
первый вызов new.


компилятор пишет, что войдовые дата-мемберы запрещены стандартом и соотв. про нижние 3 строчки пишет, что переменная автокилл не определена. других ошибок не найдено. как быть??

Код: plaintext
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.
class catcher
{ 
    public:
    static void* autoKill = 0;
    void* operator new(size_t size) 
    { 
        if (autoKill) ::operator delete(autoKill);
        autoKill = ::operator new this;
        return autoKill;
    }
    
};
class user : public catcher
{ 
    public: 
    int a;
    user(int p) { a = p; } 
};
user* globalStore = 0;
int main()
{
    globalStore = new user(5);
    globalStore = new user(6);
    
    return 0;
}



1 А почему static void* autoKill = 0 ?
Вам известен тип catcher.
Должно быть что то типа :
static catcher* autoKill;
.....
}
......
static catcher::autoKill=NULL;
....
int main(....

2. Зачем
if (autoKill) ::operator delete(autoKill); ?
что бы потом еще раз дернуть алокацию памяти ?
Если есть такое желание затрите память нулями по размеру типа.
пусть остается по тому же адресу.



3 А этого я вобще не понял
operator new this;
Откуда this ?
вы находитесь в статической функции ей фиолетов this.


Кто то был прав , относитльно желания выстрелить в ногу :)
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074871
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаРА почему static void* autoKill = 0 ?

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

чтобы решить этот вопрос я сделал автокилл ссылкой,
чтобы вместо удаления просто записывать поверх этой
выделенной памяти, но теперь компиллер запрещает
присваивать ей ноль!!

может есть какой-нибудь способ как положить
новый объект на место старого, а если старого
ещё нет, то создать это место?

Код: plaintext
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.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
#include <iostream>
using namespace std;

class catcher
{ 
    public:
    static catcher*& autoKill;
    void* operator new(size_t size) 
    { 
        autoKill = (catcher*)::operator new(size); // как тут положить объект на место старого
        return autoKill;
    }
    
};

catcher*& catcher::autok = 0; // compile err




class user4b : public catcher
{ 
    public: 
    int a;
    user4b(int p) { a = p; } 
};

class user8b : public user4b
{ 
    public: 
    int b;
    user8b(int p) : user4b(p) { b = p; } 
};




user8b* globalStore = 0;
int main()
{
    user8b* check;
    
    globalStore = new user8b(5);
    check = globalStore;
    
    globalStore = (user8b*) new user4b(6);
    cout << check->a << check->b << endl; // ещё живой!!
    
    return 0;
}





ДохтаР3 А этого я вобще не понял
operator new this;
Откуда this ?
вы находитесь в статической функции ей фиолетов this.


Я только сейчас понял, что она статическая и что ей размер дочек подсовывает компиллер... я думал явно надо указывать объем какого объекта тебе нужен...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074895
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я прошу прощения , но я в легком шоке от происходящего

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


Ну сделали так и работайте с переменной как со сылкой , а то ссылку сделали , а обращаетесь к ней
как будто она осталась указателем.
Но этот так, лирическое отсутпление , если вы хотите глубже ковырнуть принцип ссылок и указателей.
но лучше уберите ссылку нафик.

Что касается дальнейшего поведения , то что вы хотите от программы , если убрали проверку .

Не нужно ничего преразмещать ::new () должен вызываться 1 раз,
на входе в оператор вставьте проверку if (autoKill !=NULL ) throw 1 ;
и посмотрите докуда доработает ваша программа.

Она упадет на строчке globalStore = (user8b*) new user4b(6);

Вы ведь этого хотели ?

На какое поведение вам потом менять throw 1 , зависит от логики работы более высокого уровня
, извините телепаты в отпуске.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074897
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix,

Вы что, в серьез пытаетесь реализовать то что тут вам насоветовали?
Люди развлекаются между прочим.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074913
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаРНе нужно ничего преразмещать ::new () должен вызываться 1 раз,
на входе в оператор вставьте проверку if (autoKill !=NULL ) throw 1 ;
и посмотрите докуда доработает ваша программа.

Она упадет на строчке globalStore = (user8b*) new user4b(6);



Я сделал как вы сказали + убрал ссылку
Код: plaintext
1.
2.
3.
4.
5.
6.
    void* operator new(size_t size) 
    { 
        if (autok) delete autok;
        autok = (catcher*)::operator new(size);
        return autok;
    }



И у меня теперь все прекрасно компилится и все отлично работает, ничего не падает.
Результат работы программы 65.
6 это от user4b, а 5 от старой user8b
То есть new даже без ссылки отлично перезаписывает на это же самое место!!

Решение получилось супер, но оно синглтоновское...
Теперь я буду думать как это же самое решение замутить для пачек объектов
В этом решении в качестве шины использовалась статическая переменная, а что использовать для пачек... наверное какие-то общие id типа

Код: plaintext
1.
2.
3.
globalStore = new user(id1, 5)
globalStore = new user(id1, 6) // удалит, присвоит
globalStore = new user(id2, 6) // только присвоит



но на это у меня сегодня мозгов уже не хватит))) надо на свежую голову будет подумать

ДохтаР, спасиииибо!!!
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074914
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyLumix,

Люди развлекаются между прочим.

На посты типа "у меня дробовик есть" я внимание особо не обращаю))))
мой вопрос, с которым я сюда обратился РЕШЕН!!
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074916
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixмой вопрос, с которым я сюда обратился РЕШЕН!!
Ну, удачи вам.
Вернее, удачи тем, кто с этим кодом будет после вас работать :)
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38074918
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixДохтаРНе нужно ничего преразмещать ::new () должен вызываться 1 раз,
на входе в оператор вставьте проверку if (autoKill !=NULL ) throw 1 ;
и посмотрите докуда доработает ваша программа.

Она упадет на строчке globalStore = (user8b*) new user4b(6);



Я сделал как вы сказали + убрал ссылку
Код: plaintext
1.
2.
3.
4.
5.
6.
    void* operator new(size_t size) 
    { 
        if (autok) delete autok;
        autok = (catcher*)::operator new(size);
        return autok;
    }



И у меня теперь все прекрасно компилится и все отлично работает, ничего не падает.
Результат работы программы 65.
6 это от user4b, а 5 от старой user8b
То есть new даже без ссылки отлично перезаписывает на это же самое место!!

Решение получилось супер, но оно синглтоновское...
Теперь я буду думать как это же самое решение замутить для пачек объектов
В этом решении в качестве шины использовалась статическая переменная, а что использовать для пачек... наверное какие-то общие id типа

Код: plaintext
1.
2.
3.
globalStore = new user(id1, 5)
globalStore = new user(id1, 6) // удалит, присвоит
globalStore = new user(id2, 6) // только присвоит



но на это у меня сегодня мозгов уже не хватит))) надо на свежую голову будет подумать

ДохтаР, спасиииибо!!!

Не торопитесь радоваться удалением и переразмещением
вы попали пальцем в небо.
Положили револьвер со всведенным курком в карман.
Будте внимательны , неострожное движение ,
и случиться то о чем предупреждали на первой странице.

зы Я впролне серьезно.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38075540
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixможет есть какой-нибудь способ как положить
новый объект на место старого, а если старого
ещё нет, то создать это место?

Это очень похоже на описание работы шаблона "объектный пул". Или пул объектов.
(object pool). Применяется когда конструирование объектов дорого стоит и дешевле
мультиплексировать уже существующие объекты из множества доступных.

Пример - database connection pool.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38075893
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Lumix]

Можете подсказать как именно построить решение с перегрузкой new / delete конкретно для этого случая?

Чтобы сделать ЧТО ? Ещё раз объясни... Автоматом удалять объекты?


void* operator new(size_t size)
{
// как тут получить доступ к перезаписываемому
// указателю-то??

Никак. Нет тут к нему доступа.

void operator delete(void* obj)
{
::operator delete(obj);

// через что тут обнулять-то??

Не через что. Комментарии ниже.

// ведь операция удаления в самом
// общем виде не обязывает программу
// юзать указатель вообще...

Это я не понял.


Главное:
Пойми одну простую вещь: В С++ создание объекта состоит из выделения объекту памяти и инициализации в ней объекта.
Первое может вообще не происходить, если это глобальный статический или автоматический объект -- память в этом случае выделяется по-другому. Но инициализация не отличается в зависимости от размещения объекта в памяти.

Уничтожение объекта также двухстадийное и тоже независима деинициализация от размещения объекта в памяти.

В случае динамического размещения объекта выделение объекту памяти и освобождение памяти реализуется через operator new / operator delete.
Инициализация объекта и деинициализация реализуются через конструктор и деструктор

Что ты должен был бы понять из вышенаписанного относительно твоих "хотелок":
что ни operator new/delete, ни конструктор с деструктором никак не связаны с организацией автоматического удаления объектов.
Они не могут это реализовать вследствии того, как организована модель памяти в С++ -программе.

Это (garbage collector) должен реализовать какой-то другой класс, внешний по отношению к твоему. И логично это делать сразу для нескольких классов, а не для одного.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076298
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЧтобы сделать ЧТО ? Ещё раз объясни... Автоматом удалять объекты?

Удалить объект, который хранится по адресу в ссылке, в которую я хочу создать новый объект
Код: plaintext
1.
2.
3.
A* a = new A;
delete a; // как не писать эту строчку??
a = new A;




void* operator new(size_t size)
{
// как тут получить доступ к перезаписываемому
// указателю-то??

Никак. Нет тут к нему доступа.

ок, понял

void operator delete(void* obj)
{
::operator delete(obj);

// через что тут обнулять-то??

Не через что. Комментарии ниже.

ок, понял

// ведь операция удаления в самом
// общем виде не обязывает программу
// юзать указатель вообще...

Это я не понял.

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

Код: plaintext
1.
2.
3.
A* a = new A;
delete a; // как не писать эту строчку??
a = new A;



вот тут у нас два объекта
они одного типа, но они разные
первый a = 5, второй a = 6
указатель у них один
возникает вопрос как из а = 6 можно узнать, что он перезаписал чей-то чужой указатель и соотв. убить тот объект, который был в том указателе

почему я не люблю умные указатели, потому что они являются объектами и пользователи постоянно путаются, где копия, а где сам объект, а с указателями в этом смысле проще: даже если возникает копия указателя, то сам объект при этом остается сам по себе


MasterZivГлавное:
Пойми одну простую вещь: В С++ создание объекта состоит из выделения объекту памяти и инициализации в ней объекта.


я бы добавил сюда ещё третий шаг "сохранение адреса в управляющую конструкцию, чтобы всем этим можно было пользоваться", например адрес в указатель


MasterZivПервое может вообще не происходить, если это глобальный статический или автоматический объект -- память в этом случае выделяется по-другому. Но инициализация не отличается в зависимости от размещения объекта в памяти.

для простоты пользователей мы рассматриваем вариант только кучных объектов через new / delete
никаких стеков


MasterZivУничтожение объекта также двухстадийное и тоже независима деинициализация от размещения объекта в памяти.

сложность в том, как организовать связь процессов удаления/создания с процессами контроля управляющих структур (указателей)

ну и сверхзадача, спрятать все под капот, чтобы пользователи этого не видели, а только задавали графы объектов, чтобы можно было убивать куски дерева сразу, вместо всяких циклических переборок

чтобы пользватель просто вызвал delete b() и у него грамотно сдулась бы вся подсистема, которую он засунул в b()
но про деревья и каскадное убийство это не эта тема, потому что там вопросов нет, там все уже давно реализовано

конкретно эта тема про засовывание в аксессор верхнего уровня нового объекта-предка

Код: plaintext
1.
2.
3.
void stage(A* a);
stage(b());
event15() { b() = new A; }



MasterZivЧто ты должен был бы понять из вышенаписанного относительно твоих "хотелок":
что ни operator new/delete, ни конструктор с деструктором никак не связаны с организацией автоматического удаления объектов.
Они не могут это реализовать вследствии того, как организована модель памяти в С++ -программе.

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

MasterZivЭто (garbage collector) должен реализовать какой-то другой класс, внешний по отношению к твоему. И логично это делать сразу для нескольких классов, а не для одного.

тема не про GC
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076316
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixпочему я не люблю умные указатели, потому что они являются объектами и пользователи постоянно путаются , где копия, а где сам объект, а с указателями в этом смысле проще: даже если возникает копия указателя, то сам объект при этом остается сам по себе

Уволить их и все дела.
Данная задача решается только через shared_ptr.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076369
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixречь не идет об автоматическом удалении объектов в смысле автоматический поиск, потому что мы не знаем "где, когда и при каких обстоятельства мы потеряли ребенка". речь идет об автоматической зачистке , когда мы точно знаем в какой именно момент и при каком именно действии это происходит: в момент присвоения указателю нового адреса
Как мы можем это знать в рамках С++ ? Ты мог 10 раз его содержимое скопировать в другие указатели.
Кто тебя схватит за руку или запретит это сделать?
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076408
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonКак мы можем это знать в рамках С++ ?

Блин, вообще-то это я с этим вопросом сюда пришел. ))) Если бы я знал, темы бы не было...


maytonКто тебя схватит за руку или запретит это сделать?

Если вы посмотрите как я назвал класс в самом первом примере, то вы поймете, что в своих задумках (ака фантазиях) я планировал, что есть возможность создать некий интерфейс с именем catcher, который и будет хватать за руку...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076456
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixпочему я не люблю умные указатели, потому что они являются объектами и пользователи постоянно путаются, где копия, а где сам объект, а с указателями в этом смысле проще:
Проще, если не запутать и их. Вы как раз в этом направлении и двигаетесь упорно ))


Lumixтема не про GC
Был объект. Его дропнули переприсвоением. Возникает желание удалить. Неявно. Разве не простейший GC?


Lumixконкретно эта тема про засовывание в аксессор верхнего уровня нового объекта-предка
Ну и с каких делов объект-предок может решать, можно ли удалять своего коллегу?
Понятно, что в конкретной задаче можно гарантировать отсутствие каких-либо подводных камней. Но это ж не повод нарушать иерархию. Нормальную архитектуру и так сложно поддерживать в процессе разработки, а вы еще и маслица в огонь. Потом конечно "пользователи путаются". Поди разберись кто тут кто и за что отвечает!
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076465
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edd.DragonLumixтема не про GC
Был объект. Его дропнули переприсвоением. Возникает желание удалить. Неявно. Разве не простейший GC?
Если отойти в сторону то ОС является простейшим GC. Намусорил в процессе. Процесс вышел
по exit. ОС убрала мусор. Красота? Для простейших няшных ништячков типа sort.exe.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076470
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyДанная задача решается только через shared_ptr.

я сделал как вы порекомендовали
все работает!!

только почему-то shared не хочет принимать через равно внутренний объект, переданный ему через указатель... это чё мне перегрузку шареда надо мутить, да??

Код: plaintext
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.
#include <iostream>
#include <boost/shared_ptr.hpp>

using namespace std;
using namespace boost;

class A { public: int a; A() : a(5) {} ~A() { cout << "deadok" << endl; } };

shared_ptr<A> globalStore(new A);
shared_ptr<A> a(bool isNew = false) 
    { return globalStore = (isNew || !globalStore) ? shared_ptr<A>(new A) : globalStore; }
    
int main()
{
    #define pps cout << a()->a << endl;
    pps // 5
    a()->a++;
    pps // 6
    a() = a();
    pps // 6
    a() = a(true);
    pps // 5
    // a() = new A; // как можно сделать чтобы работало так?? вместо = a(true)
   
    return 0;
}
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076474
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonКрасота?
Так и делаем!
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076489
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edd.DragonПроще, если не запутать и их. Вы как раз в этом направлении и двигаетесь упорно ))

я наоборот хочу избавить их от всяких концепций shared pointer, о том, что создаются копии на границах вызовов функций и прочих вещей. Пользователи для работы с объектами пользуются только функциями, где любое первое использование создает объект b()->draw() и с new вообще никто не соприкасается ни разу

что касается примеров b() = new A, то это просто заглушка. в реале на уровне пользователя используются только функции b() = a(); и пользователь не должен думать, что же там под капотом происходит и не потечет ли у него что-нибудь...

Edd.DragonБыл объект. Его дропнули переприсвоением. Возникает желание удалить. Неявно. Разве не простейший GC?

И да и нет. ))) На мой взгляд ключевой критерий GC - асинхронность событий: перестал быть нужен и решили удалить, а в случае, который обсуждается в этой теме удаление происходит сразу, как только мы решили его удалить, в данном случае приказом на удаление является присвоение указателя


Edd.DragonНу и с каких делов объект-предок может решать, можно ли удалять своего коллегу?

С очень простых делов: он занял его указатель!! Критерий четко задан. Это и есть условие задачи.
Код: plaintext
1.
2.
3.
A* a = new A;
delete a; // как спрятать эту строчку под капот??
a = new A;




Edd.DragonПонятно, что в конкретной задаче можно гарантировать отсутствие каких-либо подводных камней. Но это ж не повод нарушать иерархию. Нормальную архитектуру и так сложно поддерживать в процессе разработки, а вы еще и маслица в огонь. Потом конечно "пользователи путаются". Поди разберись кто тут кто и за что отвечает!

Имхо в этом абзаце эмоции... Задача-то конкретная. Зачем "мировые" проблемы тут обсуждать?))))
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076532
ДохтаР
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix что касается примеров b() = new A, то это просто заглушка. в реале на уровне пользователя используются только функции b() = a(); и пользователь не должен думать, что же там под капотом происходит и не потечет ли у него что-нибудь...


Есть такой патерн , называется виртуальный конструктор,
Делайте там методы create_object, get_object, delete_object итд
и пусть через него кто как хочет тот так и управлеяет обьектами.
Какую сигнатуру определите так и будет управляться.

Зачем вы нам пудрите мозги с желанием запрятать под капот указатели и ссылки.
Прячьте их под патерн.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076570
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixИ да и нет. ))) На мой взгляд ключевой критерий GC - асинхронность событий: перестал быть нужен и решили удалить, а в случае, который обсуждается в этой теме удаление происходит сразу, как только мы решили его удалить, в данном случае приказом на удаление является присвоение указателя
А ты не боишся что требование удалять сразу является ударом по производительности?
Может быть создатели GC были не дураки и неспроста сделали освобождение памяти
для обнулившейся ссылки (обнулившийся счётчик связей) отложенным? Ты думал об этом?
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076579
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixС очень простых делов: он занял его указатель!!
И это таки мировая проблема в конкретной задачи.

Объект не занимал ничей указатель. Вдумайтесь что есть объект, что он занимает, а что есть указатель на объект, и какое к нему отношение имеет сам объект? Никакого. Указатель имеет отношение к объекту (он на него указывает). А объект к указателю - не имеет. Не знает о нем ничего. Более того, при создании объекта никого указателя нет. Есть создание объекта в памяти. А потом уже в указатель записываем адрес на эту память. При чем, ранее в этом указателе могло быть значение и факт того, что теперь в нем новое значение, еще не означает необходимость удалять прежний объект. Не новому объекту решать, нужен еще старый кому-то или уже никому не нужен. Это бред. И не важно, что именно в вашей задачи именно сейчас этот бред пока что имеет некоторый смысл. Это все-равно бред. А завтра еще и источник невероятных паранормальных явлений в вашем приложении.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076583
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДохтаРLumix что касается примеров b() = new A, то это просто заглушка. в реале на уровне пользователя используются только функции b() = a(); и пользователь не должен думать, что же там под капотом происходит и не потечет ли у него что-нибудь...


Есть такой патерн , называется виртуальный конструктор,
Делайте там методы create_object, get_object, delete_object итд
и пусть через него кто как хочет тот так и управлеяет обьектами.
Какую сигнатуру определите так и будет управляться.

Зачем вы нам пудрите мозги с желанием запрятать под капот указатели и ссылки.
Прячьте их под патерн.

У меня нет задачи пудрить вам мозги!!
Я готов реализовать что угодно, лишь бы спрятать от пользователя все сложности плюсовой архитектуры.

Объясните мне что именно вы имели ввиду под "create_object, get_object, delete_object"??? и я сделаю это

если вы имели ввиду давать эти методы в руки пользователей, то это 100% НЕТ!! задача стоит чтобы они вообще забыли, что работают с какими-то объектами, что надо какую-то память выделять и что есть какие-то правила при переносе объектов между функциями. все это надо скрыть навсегда

пользователи не должны управлять объектами!!

попробуйте попрограммировать на яваскрипте и поймете, что я имею ввиду
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076600
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonА ты не боишся что требование удалять сразу является ударом по производительности?
Может быть создатели GC были не дураки и неспроста сделали освобождение памяти
для обнулившейся ссылки (обнулившийся счётчик связей) отложенным? Ты думал об этом?


1. Нет, я этого не боюсь
2. Я оооочень серьезно обдумал все это. Первый раз когда я задумался "о смысле жизни"))) то есть о памяти, о gc и все такое это было где-то 2008-2009 год. То есть я так или иначе возвращаюсь к этой теме уже 3-4 года, потому что каждый новый успешно реализованный проект дает возможность посмотреть на эти задачи под новым более широким углом и соотв. решать более красиво.

насчет "мудрости GC архитекторов"...
ответ на ваш вопрос очень прост: они сделали отложенным очистку по одной простой причине: она автоматическая и если она будет включатся, когда ей вздумается, то она может слегка подвесить рантайм

что касается нашего варианта, то
а) я не согласен называть его GC вариантом (причины уже изложил выше)
б) пользователь сам решает когда вызывать delete stage75(); и этот вызов он спланирует так, чтобы с прикладной точки зрения это было наиболее выигрышно. классический пример: уровни в компьютерных играх: закончился уровень, почистили его и загрузили ресурсы нового уровня

что же касается обсуждаемой задачи
Код: plaintext
1.
b() = a()



то тут
а) падения нагрузки не будет
б) если кто-то по дури захочет совершить такой трюк с деревом объектов на 450 мб))) то этот факт обязательно заметят, очень быстро найдут и устранят. обращаю внимание: это факт, а не баг!! это задача оптимизации работы программы, а не задача отладки

короче, вопросы скорости тут не критичны
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076623
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edd.Dragon, я 100% понял что вы имеете ввиду, но ваши логические комбинации из речевых конструкций скорее мотивированны получением удовольствия от концептуальных форм, чем от решения конкретной задачи, тогда как если сделать конкретную задачу критерием логики, тогда часть ваших конструкций теряет силу...

Edd.DragonОбъект не занимал ничей указатель.

Код: plaintext
1.
2.
A* a = new A;
a = new A;



второй объект занял указатель первого объекта

Edd.DragonВдумайтесь что есть объект, что он занимает, а что есть указатель на объект, и какое к нему отношение имеет сам объект? Никакого.

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

Объект это просто участок памяти, а указатель это переменная которая хранит адрес на участок в памяти. В рамках обсуждаемой темы, я подчеркивают только в рамках обсуждаемой задачи, указатель считается принадлежащим тому объекту, на который он ссылается.

Код: plaintext
1.
2.
A* a = new A;
a = new A;



именно поэтому в данной задаче можно сказать, что второй объект занял указатель первого, тогда как попытка проверить валидность этих утверждений с точки зрения общей концепции языка программирования, разумеется обречена на провал

именно поэтому я в очередной раз призываю отказаться от расширения области действия используемых речевых конструкций (слов, если угодно сигнатур)


Edd.DragonУказатель имеет отношение к объекту (он на него указывает). А объект к указателю - не имеет. Не знает о нем ничего.

Сама тема возникла из-за того, что это так.
И тема создана, а как это исправить.
Вы мне как бы пытаетесь объяснить, что кусок металла весом 1 тонну не может сам улететь в космос, потому что есть гравитация. А я пришел сюда узнать как использовать ракетные двигатели, то есть как можно преодолеть ограничение.


Edd.DragonБолее того, при создании объекта никого указателя нет. Есть создание объекта в памяти. А потом уже в указатель записываем адрес на эту память.

Его нет в общем случае, но в нашей конкретной ситуации он есть!! и есть всегда!

Код: plaintext
1.
2.
A* a = new A;
a = new A;




Edd.DragonПри чем, ранее в этом указателе могло быть значение и факт того, что теперь в нем новое значение, еще не означает необходимость удалять прежний объект.

В общем случае да, но в нашем случае это 100% обозначает, что удалять надо, потому что начальное значение указателя всегда 0 и если оно не 0, значит там есть объект!!

Edd.DragonНе новому объекту решать, нужен еще старый кому-то или уже никому не нужен. Это бред.

Это не бред, а задача.)))

А вот кому решать новому, старому или какой-то иной внешней конструкции это и будет решением задачи.
Но решение о том, что прежний объект надо убить это решение принимаю я как архитектор системы и я его уже принял, сформулировав в виде задачи.


Edd.DragonИ не важно, что именно в вашей задачи именно сейчас этот бред пока что имеет некоторый смысл.

Это не просто важно, а это единственное, что имеет значение. В рамках нашей компании других источников важности просто не существует. Я есть высший источник всякой важности, точно так и вы, если конечно вы являетесь не рядовым исполнителем, тоже принимаете окончательное решение что важно, а что вторично.

Edd.DragonЭто все-равно бред.

Опять же все зависит от системы координат. Наши проекты и задачи являются бредом для вас точно так же как для вас может являться бредом речь на вьетнамском языке. Именно поэтому я в который раз отказываюсь выходить за пределы задачи и дискутировать на какие-то темы в чьих-то чужих контекстах, к которым относятся всякие "а что если..." и "а вдруг нам понадобится..."

Edd.DragonА завтра еще и источник невероятных паранормальных явлений в вашем приложении.

А вы знали, что чисто статистически 99% событий, которых опасаются люди, не случаются вообще, а те опасные события, которые и случаются, то они часто оказываются примерно в 10 раз тусклее по опасности, чем рисовало воображение, а все подлинные катастрофы происходят тогда и оттуда, откуда никто никогда не ожидал даже принципиально!!
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076649
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixтолько почему-то shared не хочет принимать через равно внутренний объект, переданный ему через указатель... это чё мне перегрузку шареда надо мутить, да??

Какая еще перегрузка шареда.
Смена объекта в смарт-указателе делается через функцию reset().

Код: plaintext
1.
2.
3.
shared_ptr<A> ptr(new A); // создали экземпляр
ptr.reset(new A); // сменили на новый
ptr.reset(); // вообще удалили



Но правильнее вообще не использоваять явно new, а создавать объекты через make_shared (<boost/make_shared.hpp>).
Код: plaintext
1.
2.
3.
shared_ptr<A> ptr = make_shared<A>(/*ctor args*/); // создали экземпляр
ptr = make_shared<A>(); // сменили на новый
ptr.reset(); // вообще удалили
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076661
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторИ тема создана, а как это исправить.
Это какое-то издевательство )))

Lumix пользователи не должны управлять объектами!!
Так на кой же вы им даете прямой доступ к чертовым указателям внутри контейнера? Почему мы только на "третий день" узнаем, что дело не в автоподтирании, а в том, что у вас какие-то проблемы с инкапсуляцией и вы не хотите видеть ее в общепринятом виде?

Пока вы не объясните причины этого, то таки это будет выглядеть как глупость, бред и возжа под хвост.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076672
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edd.DragonЭто какое-то издевательство )))

Вам уже хочется меня ударить?? ;)
Я так-то хороший... могу и просто в сторонку отойти, если градус накаляется...)))
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076675
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixВам уже хочется меня ударить?? ;)
Нет - хочется правды об этом таинственном интерфейсе!
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076686
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyКакая еще перегрузка шареда.
Смена объекта в смарт-указателе делается через функцию reset().

Хорошо, reset(), супер, отлично.
make_shared<>() круто, ништяк.

Но как мне эти штуки запаковать под капот, чтобы все работало по форме

Код: plaintext
1.
b() = new A;



тут хотя бы оператор равно появился - уже круто

Код: plaintext
1.
a = make_shared<A>();



как теперь можно спрятать этот make_shared, чтобы остался только = new A
надо class B менять или прирастить к shared_ptr::operator+()??

или может под мой случай какую-то свою легкую версию шареда написать??
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076694
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edd.DragonТак на кой же вы им даете прямой доступ к чертовым указателям внутри контейнера?

А как по вашему они должны юзать функции этих объектов-то??

под фразой юзеры не должны управлять объектами я имел ввиду они не должны управлять ими в памяти, но разумеется они управляют конфигурацями, состояниями объектов, взаимосвязями, используют их функции и т.п.



Edd.DragonПочему мы только на "третий день" узнаем, что дело не в автоподтирании, а в том, что у вас какие-то проблемы с инкапсуляцией и вы не хотите видеть ее в общепринятом виде?


У меня нет проблем с инкапсуляцией!! все с ней отлично!! задача про автоподтирание

более того, инкапсуляции-то нет, ведь указатель не хранится в объекте, а хранится глобально!! мы тут ничего не инкапсулируем. вся "инкапсуляция" происходит внутри функции b()!!
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076710
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix
вся обсуждаемая тема про то, как изнутри объекта можно управлять всеми указателями, которые на этот объект ссылаются.


Это вообще в корне неправильный подход.
Управлять жизнью объекта должен не сам объект, а кто-то другой.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076717
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixречь не идет об автоматическом удалении объектов в смысле автоматический поиск, потому что мы не знаем "где, когда и при каких обстоятельства мы потеряли ребенка". речь идет об автоматической зачистке, когда мы точно знаем в какой именно момент и при каком именно действии это происходит: в момент присвоения указателю нового адреса

MasterZivЭто (garbage collector) должен реализовать какой-то другой класс, внешний по отношению к твоему. И логично это делать сразу для нескольких классов, а не для одного.

тема не про GC

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

А если это возможно, то всё, знаешь ли, очень просто -- сокрой все методы создания и удаления объекта в классе, сделай что-то типа фабрики, но ещё и с поддержкой удаления, -- и всё, делов-то.

Только выглядеть это будет вовсе не так, как ты видимо хочеш, и совсем не по С++-овски.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076722
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЭто вообще в корне неправильный подход.
Управлять жизнью объекта должен не сам объект, а кто-то другой.

Я и не настаиваю, что должен сам объект. На шарах вон решение уже есть. Осталось совсем чуть-чуть допилить юзерскую часть...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076723
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixmaytonКак мы можем это знать в рамках С++ ?

Блин, вообще-то это я с этим вопросом сюда пришел. ))) Если бы я знал, темы бы не было...


Родной, если бы ты это знал бы, или кто другой бы знал, то уже бы вся IT-индустрия была бы лет на 100 впереди.

Для того, чтобы это сделать, надо иметь поддержку присваивания ссылок на уровне языка. Как в Java или C# или других языках с GC.
А в С++ такого нет. Зато есть ПРОИЗВОЛЬНОЕ управление памятью программистом, чего нет в вышеупомянутых языках.
Ты хочеш скрестить ужа с дикообразом ? И что получится ?
И главное зачем ?
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076734
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivА если это возможно, то всё, знаешь ли, очень просто -- сокрой все методы создания и удаления объекта в классе, сделай что-то типа фабрики, но ещё и с поддержкой удаления, -- и всё, делов-то.

Только выглядеть это будет вовсе не так, как ты видимо хочеш, и совсем не по С++-овски.

Немного не понял идею про фабрику...
Просто вот то решение, которое сейчас предложили на шарах, я разложил его на две части: сам класс class A + управляющая функция a(), которая при первом обращении к себе создает объекты, а при последующих просто возвращает уже созданный, при этом она дает доступ ко всем методам и дата-мемберам a()->draw(), a()->title = "Hello";, позволяет убивать себя как обычно delete a(), которая при этом убивает ещё и всех своих присоединенных чилдренов a()->addChild(b()) c()->setParent(a()) все это круто работает

и теперь встала задача развить функционал чтобы можно было эти горячие объекты ещё и заменять новыми объектами, без нарушения участия этого объекта в других частях программы, чтобы можно было в любой части программы подменить b() = a() или что то же самое b() = new A, при этом все остальные части программы можно не трогать

на самом деле все уже практически готово, потому что есть функционал b().reset(new A) или b().reset(a()) и остался совсем малюсенький шажок как это превратить в b() = new A ака b() = a();
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076735
Edd.Dragon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixя имел ввиду они не должны управлять ими в памяти
А ключевое слово new кто пишет?
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076736
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixMasterZivЭто вообще в корне неправильный подход.
Управлять жизнью объекта должен не сам объект, а кто-то другой.

Я и не настаиваю, что должен сам объект. На шарах вон решение уже есть. Осталось совсем чуть-чуть допилить юзерскую часть...

Так у тебя будет всегда замкнутый круг.
Если ты законтролируешь указатели на объекты в виде умных указателей, у тебя встанет проблема контролирования указателей на указатели (возможно, умные) на твои объекты. Законтролируешь этот уровень -- будет проблема со следующим. И так далее.

Тебе для твоей задачи надо просто уйти от интерфейса в виде

Код: plaintext
1.
X x = new X();



и всё будет проще.
можно использовать хэндлы, номера объектов, имена объектов (на самом деле это всё одно и то же), что хочеш. И тебе сразу станет проще.

Тебе нужно чтобы при перезаписи старое удалялось ? Напрямую реализуй эту концепцию в своём классе, сделай там слоты для объектов, и дай пользователям возможность в слотах создавать и удалять объекты. НЕ ДАВАЯ им доступ к объектам напрямую,
инкапсулируя все операции с этими объектами по слотам.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076739
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробую потом написать код, как это примерно будет выглядеть....
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076746
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivДля того, чтобы это сделать, надо иметь поддержку присваивания ссылок на уровне языка.

На самом деле я уже давно понял, что чистыми указателями эту задачу не решить, поэтому стал активно развивать тему с шарами, потому что они дают все те же самые плюшки, что и указатели, то есть можно забыть про границы функций и при этом они позволяют вешать крючки на события. В данном случае меня интересует событие operator=()

MasterZivТы хочеш скрестить ужа с дикообразом ? И что получится ?
И главное зачем ?

GC я не строю. Это глупо. А задачу на лету потереть старый объект и на его место в памяти прошить новый объект это вполне реально. По сути дела, я спрятал все действия по работе с памятью за один интерфейс, которым в данном случае является функция аксессор a()

то есть во всем коде, пользователь пишет как ему надо и использует функцию a(), а какие именно объекты, какие именно участки памяти там используются это управляется в другом месте, например, в контроллерах событий a() = b()
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076750
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Edd.DragonА ключевое слово new кто пишет?

Функция аксессор при первом обращении. При любом первом обращении!!

пользователь пишет
Код: plaintext
1.
2.
3.
a()->draw1() // new тут
a()->draw2()
a()->draw3()



удалил первую строчку

Код: plaintext
1.
2.
a()->draw2() // а теперь тут
a()->draw3()



в общем, кто первый вызвал, тот и папа
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076773
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЕсли ты законтролируешь указатели на объекты в виде умных указателей, у тебя встанет проблема контролирования указателей на указатели (возможно, умные) на твои объекты.

Я немного не понял зачем share_ptr контроллировать??... Неужели есть случай, когда и на них образуются висяки?? ведь мы абсолютно все операции с ними спрятали под капот аксессоров... в пользовательском коде вообще нигде ни разу не должно всплыть share_ptr ни разу!! они вообще не должны знать что такое есть вообще!!




MasterZivТебе для твоей задачи надо просто уйти от интерфейса в виде

Код: plaintext
1.
X x = new X();



и всё будет проще.
можно использовать хэндлы, номера объектов, имена объектов (на самом деле это всё одно и то же), что хочеш. И тебе сразу станет проще.

А у нас такого и нет вообще. Это я просто для примера тут приводил.

У нас вообще нет объектов в пользовательской части, только функции. Объекты только данных: строки, числа, картинки, кисти и т.п., т.е. вся расходка. Все остальное существует только в виде функций, т.е. все спрятано под капот.

Глобальные номерки это все уже есть и все работает. То есть у каждого аксессора уже гарантировано есть a()->gloId, a()->className и другая мета, но я пока не придумал как это можно заюзать для решения задачи, обсуждаемой в этой ветке.

MasterZivТебе нужно чтобы при перезаписи старое удалялось ? Напрямую реализуй эту концепцию в своём классе, сделай там слоты для объектов, и дай пользователям возможность в слотах создавать и удалять объекты. НЕ ДАВАЯ им доступ к объектам напрямую,
инкапсулируя все операции с этими объектами по слотам.

Немного не понял...

Любой объект уже можно БЕЗОПАСНО удалить через delete a(); а любой последующий вызов a() создаст новый объект. Сейчас задача про a(1) = a(2), чтобы а(1) при этом потерся из памяти и записал на свое место a(2), чтобы они в итоге оба указывали на одно и то же.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076776
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivПопробую потом написать код, как это примерно будет выглядеть....

ok
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076836
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix
Код: plaintext
1.
a = make_shared<A>();



как теперь можно спрятать этот make_shared, чтобы остался только = new A

Это требование бессмысленно.
Не надо вообще работать с new и голыми указателями.
Смартуказатель предоставляет АПИ для всех необходимых операций с указателем и объектом.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076842
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А "решение" основанное на перегрузке new/delete - выкинуть к е...ням.
Черта с два оно безопасно.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076894
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не, я реально не понимаю, что же человеку надо...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38076904
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivНе, я реально не понимаю, что же человеку надо...
А что тут непонятного? Перед нами ситуация, когда человек уровня в лучшем случае джуниора занимается дизайном архитектуры, и при этом судя по всему является тем, кто принимает окончательные решения.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077168
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivНе, я реально не понимаю, что же человеку надо...

На данный момент все решено и сузилось до этой задачи

Код: plaintext
1.
2.
3.
4.
5.
6.
A* getA(); // внешняя либа

shared_ptr<A> globalStore = make_shared<A>();
shared_ptr<A> a() { return globalStore; }

a().reset(getA()); // как можно записать эту строчку в виде a() = getA(); 



PS. И ещё вы намекали, что в этой схеме есть какие-то риски использования шаредов и поэтому их требуется "законтролить"... что имелось ввиду я так и не понял...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077184
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyПеред нами ситуация, когда человек уровня в лучшем случае джуниора занимается дизайном архитектуры, и при этом судя по всему является тем, кто принимает окончательные решения.

Все это так!! только про джуниора не понятно)))... может быть настоящих джуниоров давно не видели? ;)
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077188
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyЭто требование бессмысленно.
Не надо вообще работать с new и голыми указателями.
Смартуказатель предоставляет АПИ для всех необходимых операций с указателем и объектом.

Голые указатели отдают функции, которые мы не контроллируем. Я согласен, что их надо завести под шареды, но пользователи не будут этого делать сами. Эта упаковка должна происходит автоматически, поэтому и возник вопрос как можно спрятать эту операцию в оператор =()
Код: plaintext
1.
2.
3.
a() = make_shared<A>(); // хуже, надо вручную писать имя типа
a().reset(getA()); // лучше, это есть в кодкомплите
a() = getA(); // идеальный вариант с точки зрения пользователя
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077286
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixAnatoly MoskovskyЭто требование бессмысленно.
Не надо вообще работать с new и голыми указателями.
Смартуказатель предоставляет АПИ для всех необходимых операций с указателем и объектом.

Голые указатели отдают функции, которые мы не контроллируем. Я согласен, что их надо завести под шареды, но пользователи не будут этого делать сами. Эта упаковка должна происходит автоматически, поэтому и возник вопрос как можно спрятать эту операцию в оператор =()
Код: plaintext
1.
2.
3.
a() = make_shared<A>(); // хуже, надо вручную писать имя типа
a().reset(getA()); // лучше, это есть в кодкомплите
a() = getA(); // идеальный вариант с точки зрения пользователя

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

Кроме того, у вас хромает логика, это следствие плохого понимания того что вы делаете. Например:
Код: sql
1.
a() = getA(); // идеальный вариант с точки зрения пользователя

вы называете идеальным вариантом, в то время, как вам он на самом деле представляется "не идеальным", так как идет работа с raw-указателями. Понятно, что имеется в виду форма записи, но форма не может существовать без содержания, в этом у вас и противоречие - надо именно так, да и не так вроде.

А ситуация действительно типовая, есть фабричные функции возвращающие "опасные" указатели, надо всего-то обернуть их в безопасные, то есть написать кучу оболочек для этих фабричных функций:
Код: sql
1.
 a() = getSafeA(); 

, а не придумывать грабли с неявным преобразованием, пытаясь превратить программирование на плюсах в программирование на javascript (для ваших "клиентов"). Кстати в этом я вижу корень ваших проблем судя по топикам, вы не можете четко осознать что плюсы это не GC-ruled язык, в том смысле что здесь не нужно скрывать с чем вы имеете дело под мусором неявных преобразований, более того, нужно наоборот как можно более четко давать понять какие объекты языка фигурируют в данной строчке кода. Об этом вам тоже не раз сказали и показали как это сделать.

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

ps. То как вы инициализируете синглтон тоже вызывает вопросы, но это другая тема, где тоже можно делать много шума из ничего.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077297
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

по поводу рисков использования шаредов мне в соседней ветке объяснили 13624428
Похоже, что использование ссылок на шареды полностью закрывает риски, о которых вы говорили...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077438
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_столько шуму делаете из стандартной типовой ситуации

поймать перезапись указателя, а это и была тема этой темы, оказалось не то, что типовой ситуацией, а вообще принципиально невозможной, поэтому пришлось использовать умные указатели в форме шаредов, чтобы использовалось автоматическое затирание объектов в памяти, которые стали недоступны при перезаписи указателя b().reset((B*) new A)

задача решилась, все круто и теперь остался последний шажок, как это спрятать под капот в форму b() = new A; но для этого я создал отдельную тему 13624428

по большому счету эту тему уже можно закрывать, так как ответ в ней уже найден: чтобы поймать факт перезаписи надо использовать шареды, причем со ссылкой

а как теперь спрятать этот кастинг под капот, это решение я ищу в соседней ветке


sherzod_более того совершенно не пытаетесь понять что вам втолковывают

чтобы вы наконец задумались над тем что вам говорят

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

sherzod_Кроме того, у вас хромает логика, это следствие плохого понимания того что вы делаете. Например:
Код: sql
1.
a() = getA(); // идеальный вариант с точки зрения пользователя


вы называете идеальным вариантом, в то время, как вам он на самом деле представляется "не идеальным"

Вам кажется, что у меня хромает логика по одной простой причине, что вы верите, что существует некое на самом деле . Я это называют попыткой сменить задачу или контекст.

Как известно любому образованному человеку, любая логическая система, будучи непротиворечива сама себе, всегда содержит в себе критерий, который недоказуем средствами системы и поэтому для носителя такой логической системы этот критерий остается незамеченным. Чем-то это похоже на запах в центре йоги, который мы не замечаем, когда находимся там некоторое время, но сразу же замечаем, как только вошли с улицы.

Так и вы: у вас какие-то внутренние критерии-аксиомы, к которым вы привыкли за долгие годы и просто уже не замечаете, но эти критерии продолжают оказывать влияние на ваши выводы в отношении логических систем других людей, например, моей логики и она кажется вам хромающей.

А кроме того, для некоторых спецов часто актуальна проблема профессиональной гордости, которая проявляется в существовании лишь двух вариантов исходов ситуации: либо я знаю как решить, либо задача ошибочная. Вариант, я не знаю как решить для таких спецов исключен.


sherzod_А ситуация действительно типовая, есть фабричные функции возвращающие "опасные" указатели, надо всего-то обернуть их в безопасные, то есть написать кучу оболочек для этих фабричных функций:
Код: sql
1.
 a() = getSafeA(); 

, а не придумывать грабли с неявным преобразованием, пытаясь превратить программирование на плюсах в программирование на javascript (для ваших "клиентов").

Ремарочка: не знаю насколько эта задача типовая, но в викидеии на анлийском языке примеров фабричного метода не существует, что как бы намекает на "типовой" характер...)))

Если бы наша команда решала бы все свои задачи явными преобразованиями, то наш код верхнего уровня превратился бы в дерьмо, потому что джуниоры потеряли бы предметный код среди обслуживающего. Я для того и существую, чтобы джуниоры работали над предметной конкретикой и не лезли бы под капот.

sherzod_Кстати в этом я вижу корень ваших проблем судя по топикам, вы не можете четко осознать что плюсы это не GC-ruled язык

Я это отлично понимаю и в наших проектах нет ни одного сборщика мусора!!
Мне тут один товарисчщ чуть выше уже пытался подкинуть вирус, что типа деструктор это лайтверсия GC, но я отказался расширять логический контекст.

sherzod_в том смысле что здесь не нужно скрывать с чем вы имеете дело под мусором неявных преобразований, более того, нужно наоборот как можно более четко давать понять какие объекты языка фигурируют в данной строчке кода.

У слова нужно всегда есть субъект. Всегда есть тот кому нужно. Если вам не нужно, то ради бога. А конкретно нам нужно. Мы это не вы. И вы похоже об этом забываете. Я знаю людей, которые очень настойчиво будут вам объяснять, что пиво нужно пить только с водкой и вы никогда их в этом не переубедите, а если вы будете настаивать, то все может закончится очень печально. Поэтому очень важно помнить, что у вас свои нужно, а у нас свои нужно.

sherzod_Об этом вам тоже не раз сказали и показали как это сделать.

"Об этом" это о чем?? и какой конкретный пример вы имеете ввиду?? Я обработал все примеры этой ветки.

sherzod_В данном случае советую прежде всего спокойно сделать то что вам советуют

Какой конкретный совет, решающий мою задачу вы имеете ввиду?? номер поста можете привести??

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

Мне в этой теме инициализация тоже ни разу неважна, я даже не обращаю на это внимание, что там написано. Мое внимание занимает лишь одна строчка пользовательского уровня и решение для неё я и ищу.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077471
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На хабре пишут про проблему циклических ссылок.
Кто-то сымитировал это?
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077566
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix,

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

Код: plaintext
1.
2.
1. Используйте смартуказатели (это вы после того как вас с ними познакомили, и таки надоумили использовать, вроде сделали).
2. Делайте это явно. С помощью фабричной функции*, фабрики или явным оборачиванием как вам раза три показал Анатолий. **


* Не фабричным методом, такого понятия не существует в с++, за пояснениями - в стандарт, книги, в комитет и в др. авторитетные источники, так как не очень приятно объяснять тому кто не слушает.
** Заранее согласен что у вас есть свой взгляд на вещи, можете делать по своему, эти два совета - всего лишь советы.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077713
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixГолые указатели отдают функции, которые мы не контроллируем. Я согласен, что их надо завести под шареды, но пользователи не будут этого делать сами.


Так просто возвращай эти указатели, и всё. Если боишся, что пользователь выдернет указатель из смарт указателя,
вообще перепиши его так, чтобы не было доступа прямого к нему (сделай свой вариант смарт указателя)
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077738
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНа хабре пишут про проблему циклических ссылок.
Кто-то сымитировал это?

А чё тут имитировать ?
И это вовсе не проблема.
Это проблема для универсальных GC, когда они действуют вне логики работы приложения и не знают о ней.
А когда пишеш руками сам, всегда есть возможность разорвать цикл и те же SharedPtr будут замечательно работать.
Смартпоинтеры работают всегда внутри логики работы приложения, в этом их плюс.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077752
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не, я не понимаю, что ж ему надо и зачем.
И что-то я уже потерял нить ...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077832
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv, я вот думаю, может подобные дискурсы переносить в ПТ. Там и юмор и контингент особый. Готовый ко всему...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38077929
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivНе, я не понимаю, что ж ему надо и зачем.
И что-то я уже потерял нить ...

Тему уже можно не читать, все давно решено. Просто подскажите насколько безопасно, если я прикручу к shared_ptr перегруженный оператор =, чтобы в нем производить операцию даункастинга.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38078007
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
есть у меня ещё запасной вариант, если решение с оператором равно найти не удастся
но этот вариант не компилится из-за динамик каста...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
#include <boost/shared_ptr.hpp>
using namespace boost;

class A {};
class B : public A {}; 

shared_ptr<B> globalStore((B*)0);
shared_ptr<B>& b() { return globalStore = globalStore ? globalStore : shared_ptr<B>(new B); }
shared_ptr<B> b(A* p) {  return dynamic_cast<shared_ptr<B> >(shared_ptr<A>(p)); }
shared_ptr<B> b(B* p) {  return shared_ptr<B>(p); }

int main()
{
    b() = b(new A);
    return 0;
}
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38078121
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixГолые указатели отдают функции, которые мы не контроллируем. Я согласен, что их надо завести под шареды, но пользователи не будут этого делать сами. Эта упаковка должна происходит автоматически, поэтому и возник вопрос как можно спрятать эту операцию в оператор =()
Код: plaintext
1.
2.
3.
a() = make_shared<A>(); // хуже, надо вручную писать имя типа
a().reset(getA()); // лучше, это есть в кодкомплите
a() = getA(); // идеальный вариант с точки зрения пользователя



Автоматически - не выйдет.
Юзер должен будет явно преобразовать в смарт.
Вы ему можете помочь сократить кол-во буквочек:

Код: plaintext
1.
2.
3.
4.
5.
6.
template <class T> boost::shared_ptr<T> to_shared(T* obj)
{
    return boost::shared_ptr<T>(obj);
}

boost::shared_ptr<A> pa = to_shared(raw_ptr);



Только помните, что shared_ptr это совместное владение и удаляет объект последний оставшийся владелец.
Т.е. голый указатель (точнее его объект), который вы получаете из внешних функций, не должен потом удаляться другим способом чем через созданный shared_ptr (в том числе и через другой shared_ptr, не являющийся копией этого).
Из этого следует например то, что та внешняя функция которая возвращает голые указатели не должна возвращать один и тот же указатель более одного раза. Т.е. она каждый раз должна создавать новый объект.
Но у вас судя по всему и так создаются новые объекты, раз вы озаботились их удалением.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38078169
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyАвтоматически - не выйдет.
Юзер должен будет явно преобразовать в смарт.
Вы ему можете помочь сократить кол-во буквочек:

Код: plaintext
1.
2.
3.
4.
5.
6.
template <class T> boost::shared_ptr<T> to_shared(T* obj)
{
    return boost::shared_ptr<T>(obj);
}

boost::shared_ptr<A> pa = to_shared(raw_ptr);



вместо to_shared() я принял решение дать ему перегруженный аксесссор


Anatoly MoskovskyТолько помните, что shared_ptr это совместное владение и удаляет объект последний оставшийся владелец.
Т.е. голый указатель (точнее его объект), который вы получаете из внешних функций, не должен потом удаляться другим способом чем через созданный shared_ptr (в том числе и через другой shared_ptr, не являющийся копией этого).

сейчас у нас удаление происходит через delete b();
но если мы переведем все на шарепоинты тогда delete перестанет работать и придется весь код переписывать на b().reset()
я сейчас думаю над этим вопросом...

b() у нас всегда ссылка, и разумеется delete b(new B) исключены

Anatoly MoskovskyИз этого следует например то, что та внешняя функция которая возвращает голые указатели не должна возвращать один и тот же указатель более одного раза. Т.е. она каждый раз должна создавать новый объект.
Но у вас судя по всему и так создаются новые объекты, раз вы озаботились их удалением.

а из-за шарепоинтов у нас сейчас получается указателей-то вообще нет ни одного...
типа теперь все аксессоры возвращают поинтеры

поинтеры появились на сцене чтобы b(1) = b(2) не создавало утечек с b(1)
но теперь потерялась возможность делать delete b()
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38078352
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все, нет сил смотреть на это - я сдаюсь :)
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38078357
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix, а ты что-нибудь писал на managed C++, на C# или Java ?
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38078503
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyВсе, нет сил смотреть на это - я сдаюсь :)

Анатолий, на всякий случай, если я не появлюсь на этом форуме до нового года, мне хотелось бы поздравить вас с наступающим, потому что вы и МастерЗив мои самые любимые персонажи на С++ ветке sql.ru Спасибо за классное общение!! Желаю вам в наступающем году змеи быть изворотливым и хитрым ради собственных интересов. Ну и здоровья конечно!!
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38078521
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonLumix, а ты что-нибудь писал на managed C++, на C# или Java ?

У нас нетбинс, mingw, винда/линь/макос, пхп и js. Других технологий нету. Команда ещё ждет, когда я наконец-то скажу мяу по поводу иоса и ведроида, но че-то я пока не созрел...

Кстати, не последнюю роль в том, что я пока жду - это отсутствие раздела на sql.ru
Даже sharepoint есть, а иоса и андроида нету...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38079179
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix, просто... может С++ это не твоё? Думал об этом? Если уж так тяжело даётся дружба
с системным языком (а он действительно близок с системному а не прикладному) то зачем
насиловать себе мозг? Кроме того по постам - у тебя гуманитарный склад ума.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38079736
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonLumix, просто... может С++ это не твоё? Думал об этом?

Думал конечно. Думал на шарп перевести команду или на яву. Но ведь это проприетарные платформы и никогда не знаешь что с ними станет. Ещё я со всякими умными дяденьками советовался, которые к нам в екб приезжали и они сказали, что в условиях современного мира С++ будет только развиваться, что мода на него ещё придет.

Кроме того, важно понимать, что мозг придется напрягать в любом случае, даже в том же шарпе или в яве и глупо думать, что там все медом мазано. К тому же у нас уже есть наработки, есть команда, есть опыт в с++


maytonЕсли уж так тяжело даётся дружба с системным языком (а он действительно близок с системному а не прикладному) то зачем насиловать себе мозг?

Мы его используем 100% как прикладной инструмент, который позволяет создавать а) бинарники, б) кросс-платформенный код. Ну помучился я пару дней с памятью, ну вник я в эти заморочки с кастингом и указателями, ну доработаю я эти аксессоры и все, сдал в продакшен и этим можно пользоваться на трогая и не вникая. То есть эти мучения носят разовый характер.


maytonКроме того по постам - у тебя гуманитарный склад ума.

Да, склад ума гуманитарный, это не вызывает сомнений, но мне кажется, что мастерство программирования очень много содержит в себе именно гуманитарных талантов, требует хорошего воображения и чувства стиля.

К тому же у меня есть совершенно дикая мечта, которую я пока не знаю как реализовать... мне хотелось бы выучить хаскель настолько, чтобы можно было обучить команду джуниоров производить продукты, востребованные рынком. Я уже три раза делал заход на хаскель, но как обучить ему джуниоров я так и не допер... А на с++ я джуниора, который знает пхп, спокойно могу за пару месяцев научить и он начнет справляться с задачами из нашего багтрекера.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38079765
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix, как только ты перейдешь на другой (высокоуровнеый) ЯП то забудешь свои мучения
как страшный сон. Нет правда. Тебе не нужен С++. У тебя от него зуд в одном месте
и болезни сердца и почек. И те проблемы с которыми ты воюешь они в продуктиве
не нужны. С ними просто никто не воюет. Меняют быстро постановку и пишут
боевой код. Никто new не перегружает!
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38079804
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonкак только ты перейдешь на другой (высокоуровнеый) ЯП то забудешь свои мучения
Ага, на хаскель надо переходить. Ну, так чтоб сразу в морг
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38079834
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я имел в виду Lua.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38079898
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyАга, на хаскель надо переходить. Ну, так чтоб сразу в морг

ну за 10-15 лет может как-то просветление наступит))) это просто в качестве сверхамбициозной мечты...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38079920
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonLumix, как только ты перейдешь на другой (высокоуровнеый) ЯП то забудешь свои мучения
как страшный сон. Нет правда.

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

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

Если бы нас под дулом пистолета заставили бы слезть с плюсов, то мы скорее всего пересели бы на яву, но никак не на луа.


maytonТебе не нужен С++.

Нужен, нужен. )))

maytonУ тебя от него зуд в одном месте и болезни сердца и почек.

Нет у меня от него никакого зуда. Обычная рабочая нагрузка. Мало чем отличается от банальной отладки.

maytonИ те проблемы с которыми ты воюешь они в продуктиве не нужны. С ними просто никто не воюет.

Разумеется они не нужны, потому что кто-то эти проблемы однажды решил и все спрятал под капот, сдав в продакшен понятный и комфортный интерфейс.

mayton Меняют быстро постановку и пишут боевой код. Никто new не перегружает!

В бою new вообще нет. Это все спрятано под капот. Да и в обсуждаемых темах в итоге перегрузка new не потребовалась...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38087523
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ответ на самый верхний пост -- можно, это делает либа под названием boehm gc

На днях я ее ковырял, было интересно как же она работает. Оказалось - просто. Она анализирует стек. Во всех архитектурах в стек пушается только числа фиксированной ширины, на i386 это 4байта, на 64 архитектуре 8... В стеке хранятся адреса возвратов и локальные переменные. И если локальная переменная - указатель, то можно посмотреть куда он указывает, а если есть список ранее выделеный участков памяти, то можно просмотреть есть ли в стеке указатель на этот участок.
вот так она и работает.

Ну и плюс куча извращений и костылей по получаения адреса стека одного потока из другого.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38087563
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм... если идти по ссылкам от страницы этого boehm gc то можно найти интересные статьи
и ссылки на книги

http://www.memorymanagement.org/
http://www.iecc.com/gclist/GC-faq.html
http://www.cs.kent.ac.uk/people/staff/rej/gcbook/gcbook.html
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38087591
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok,

А какой костыль решает такое?
Код: plaintext
1.
2.
3.
4.
5.
// swap
register tmp = ptr_a;
ptr_a = ptr_b;
// вот в этот момент нигде в памяти нет указателя ptr_a, но он по прежнему используется
ptr_b = tmp;
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38087597
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да.. сомнительно как-то. В Java декремент счётчика ссылок происходит
при потере scope. Это логично. Это надёжно. Вышел из скоупа - значит
референс потерял -1. Как можно анализируя стек (множество стеков!)
принять решение о том что объект можно удалять? Мистика.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38087608
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Да проблема поиска по стекам ничем от кучи не отличается (на стеке даже проще, т.к. он однопоточный).
Но любой самый захудалый компилятор использует регистры для временных переменных.
Интересно как это решается в boehm.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088000
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это вы меня спрашиваете??? Это я вас хочу спросить.

но если вам интересно мое мнение -- очевидно, программист должен понимать как работает эта либа, и пользоваться ею правильно. Вот вы, например, моментально поняли, я втыкал в нее полдня... В контексте вашего вопроса это означает - так как вы предложили, делать не надо. В плюсах много вещей, которые сделать можно, но не следует. Сама эта либа, насколько я понимаю, появилась раньше языков с mark&swep, обвинять ее том, что ее предерали с оных было бы глупо, однако сегодня она выглядит именно так.

Мне кстати удавалось ее обмануть без регистров. Она, помимо стека, анализирует (по всей видимости, рекурсиво) указатели, которые там хранятся. То есть если заалоцировать указатель:

int **p = (int **) GC_MALLOC(sizeof(int *));

и потом заалоцировать еще блок памяти, присвоив его этому указателю

(*p) = (int *)GC_MALLOC(50);

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

но если мы заалоцируем массив и попытаемся его использовать:

int **p = (int **) GC_MALLOC( 10*sizeof(int *) );
p[5] = (int *) GC_MALLOC( 50 );

То либа "не видит" все, что дальше p[0].


mayton В Java декремент счётчика ссылок происходит при потере scope. Это логично. Это надёжно. Вышел из скоупа - значит референс потерял -1
Тут корректней было бы говорить о конкретном GC конкретной jvm. Только в оракловкой jvm их вроде 3 штуки разных. В проекте cacaovm их две, одна из которых - boehm. gcj тоже на boehm базируется. К тому же, даже если в яве подсчет ссылок есть, он служит для оптимизации, потому что бывают еще и циклические ссылки, и там подсчет бессилен.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088022
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Off
chabapok, ты вырос в моих глазах. Особенно если сравнить твои
посты которые ты писал раньше. Будто человека подменили.
Рработяга...
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088034
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
насчет того, что компилятор может самовольно сделать так, как вы пишите, засунув самовольно указатель - в регистр. gcc так не делает, по крайней мере с ключиком -O2
Но если с какими-то ключиками он будет так делать, то тогда надо будет использовать модификатор volatile там, где он нужен. Однако, насколько знаю, самовольно регистры он никогда не использует по той причине, что даже в однопоточной программе это может приводить к трудноуловимым ошибкам.

Если у нас есть указатель int* x; то нет никакой гарантии, что в программе нету int **y, который в какой-то момент времени начнет указывать на x. И если компилятор самовольно засунет x в регистр, то это будет совсем не то, что хотелось программисту, поэтому компилятор так не делает (возможно, ключик у него все же есть какой-то). поэтому, если такая оптимизация руками не включена, то можно не опасаться, ну а если эту оптимизацию включили - ссзб, ибо она даже по документации dangerous.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088118
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokнасчет того, что компилятор может самовольно сделать так, как вы пишите, засунув самовольно указатель - в регистр. gcc так не делает, по крайней мере с ключиком -O2
Но если с какими-то ключиками он будет так делать, то тогда надо будет использовать модификатор volatile там, где он нужен. Однако, насколько знаю, самовольно регистры он никогда не использует по той причине, что даже в однопоточной программе это может приводить к трудноуловимым ошибкам.
Что значит не делает?
Еще как делает. Ведь на большинстве платформ невозможно скопировать память-память без промежуточного регистра.
Хоть volatile хоть не volatile.

Ну и пример кода генерируемого -О2
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
int a = 1;
int b = 2;
int* volatile pa = &a;
int* volatile pb = &b;

int main()
{
    int* tmp = pa;
    pa = pb;
    pb = tmp;
    return *pa - *pb;
}



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    movq    pa(%rip), %rax
    movq    pb(%rip), %rdx
    movq    %rdx, pa(%rip)
    // вот здесь прежнее значение pa хранится только в регистре RAX
    movq    %rax, pb(%rip)
    movq    pa(%rip), %rax
    movq    pb(%rip), %rdx
    movl    (%rax), %eax
    subl    (%rdx), %eax
 
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088232
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм, проверил - действительно, потенциальная проблема имеет место.

Я думаю, этот неочевидная то ли фича то ли баг лежит на совести программиста. Странно, но по этой проблеме навскидку вообще ничего не нагугливается.

Волатильной в этом примере должна быть tmp. Делаем:

int* volatile tmp = pa;

и тогда получаем:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	movq	pa(%rip), %rax
	movq	%rax, -8(%rsp)
	movq	pb(%rip), %rax
	movq	%rax, pa(%rip)
	movq	-8(%rsp), %rax
	movq	%rax, pb(%rip)
	movq	pa(%rip), %rax
	movq	pb(%rip), %rdx
	movl	(%rax), %eax
	subl	(%rdx), %eax
	ret



х86 ассемблер не мой конек, но похоже, теперь все ок.

Однако этот "баг", если делать без volatile, проявится только в многопоточной программе.

Еще одна особенность работы gcc в том, что он удаляет локальные переменные не при выходе из области видимости, а сразу когда она больше не нужна. Если экспериентировать с детектором утечек памяти который идет в составе boehm, то это очень хорошо видно.

получается, что boehm убирает одни проблемы, но зато вносит другие. И так и знал, что подвох обязательно будет. :((
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088280
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok,

А другая ситуация.
Если указатель указывает в середину массива, то ловится ли такое?
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088320
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok,

насколько я понял либа не предназначена для прямого использования в программах на С и С++. Скорее для встраивания в VM языки, используя прослойку C/C++. Да и невозможно это, использовать ее прямо, принимая во внимание ограничения которые либа неизбежно должна накладывать на операции с указателями, которые далеко не ограничены регистровыми переменными, указателями на указатели, упаковыванием адреса в целое, косвенной адресацией, арифметикой, наличием указателей на функции, на функции-члены, полиморфизмом, кастами и тд и тп. скоро конец света, перечислить все не успеется, лучше за оставшееся время почитать кучу полезной инфы на сайте проекта, за что вам спасибо :).
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088336
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Когда я пробовал, вроде ловилось, но если захочу так делать - еще раз это хорошенько протестирую.

То есть, если мы потеряем указатель на начало блока данных, но у нас будет указатель на его середину - этот блок все равно не будет освобожден.

Еще, похоже что, либа хранит в своем хипе контрольные суммы свободных блоков. Не знаю хорошо это или плохо, не знаю отключаемо ли это. Если мы где-то вылезли за пределы отведенной нам памяти и сделали туда запись, то когда-нибудь при очередном выделении памяти, этот gc находит испорченый блок и предупреждает нас. Там с либой этой идут тесты для нее, и в вних есть тест на такой функционал.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088415
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_,

1. указатели на указатели либа ловит, но с ограничениями (см 13665184 где я описал этот случай), на то он mark&sweep.

2. Регистровые указатели вообще сомневаюсь что можно поймать, поэтому тут надо быть осторожным

3. упаковыванием адреса в целое само по себе не есть проблемой, потому что:
- адрес как правило все равно хранится в стеке
- если адрес уже перестанет хранится, а останется само целое, то его представление побайтово равно указателю и с точки зренния gc им будет являтся, поэтому пока это целое будет существовать в стеке или в хипе (с ограничениями п.1)- память не будет освобождена

4. косвенной адресацией, арифметикой -- не знаю что есть косвенная адресация, а арифметика сама по себе, как мы выяснили, не должна портить указатели, если происходит над волатильными переменными

5. наличием указателей на функции, на функции-члены, полиморфизмом, кастами
Для плюсов там есть плюсовый аллокатор.

Что же касается указателя на функцию, то функции не хранятся в хипе. GC смотрит куда указатель указывает -- не в хип. И это все, что ему надо. Если он встретил что-то, что указывает не в его хип -- это либо чужой указатель, либо вообще не указатель, его трогать не надо и не надо никак обрабатывать. Точно так же адреса возврата gc не будет никак обрабатывать, потому что они не указывают на его хип.

При этом, конечно, если побайтовое представление нескольких переменных нечаянно начнет "указывать" на хип - gc этот блок не высвободит. Поэтому, в большой программе неизбежен некоторый оверхед.

что-там будет с указателями на фукнцию-член обьекта - точно сказать не могу, но по идее должно работать, потому что указатель на сам обьект gc должен подхватить и корректно обработать.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088490
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok,

Это просто высший класс! Давно не было такого четкого конкретного, без отвлечений, полного предметного ответа :). Согласен с каждым пунктом. За исключением того, что все же эту библиотеку вряд ли можно с разумными затратами на написание кода использовать прямо в программах на С и С++.

Кстати думаю вы все же ответили на вопрос ТС о возможности отслеживания изменения указателя, но цена не та и переносимость тоже.

И все же есть некоторые малозначимые поправки, упаковка в целое не обязана быть представлением адреса (вспомните про знаковые). Косвенная адресация и арифметика, это может быть все что угодно, что хранит адрес в разобранном виде и однажды собирает его, например простой случай, упомянутый Анатолием, хранения указателя на середину массива (потом можно вычислить и начало), насколько я понял этот случай ловится вычислением входимости в диапазон (но тогда возникают серьезные претензии к скорости, будет больше константы, по крайней мере логарифм точно, хотя что ж, это сборка мусора).

Если учитывать все ограничения от языка останется ни на что не годный обрубок. Ну может для чего-то вроде локальных std::vector< class T , gc_allocator<class T> > и подойдет, но уж явно не для полного избавления программы от ручного управления памятью. Ну что спорить-то :), либа явно не для ручного кода.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088503
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_std::vector< class T , gc_allocator<class T> > Здесь конечно стормозил, имелся в виду какой-нибудь пользовательский контейнер вместо std::vector, в котором не нужно отслеживать освобождение памяти элементов.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38088584
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторЗа исключением того, что все же эту библиотеку вряд ли можно с разумными затратами на написание кода использовать прямо в программах на С и С++.

Ну это уже больше следствие личных предпочтений и неприязней. Я, например, вообще не понимаю зачем для крупных вещей сегодня пользовать плюсы если есть ява - это к вопросу о "разумности затрат".

Насчет цены и переносимости. Как оно работает с большим хипом и большим количеством обьектов - я не знаю. Насчет переносимости -- этот gc портрован на много разных архитектур. Если заглянуть в его configure, там даже амига есть, есть упоминание архитектур в которых стек растет вверх а не вниз...

я с этим gc познакомился чуть ближе, когда пытался откомпилить cacaovm для qnx6 под i386. В портах оказалась только потоко-опасная версия. Пока мне не удалось это сделать, т.к. в qnx6 некорректно работает получение sp другого потока. Пока у меня не вышло с этим ничего сделать, и я на это забил, но думаю вернутся по свободе. Но это - исключение. Этот gc уже портирован на большинство известных архитектур большинства ОС. Если же надо что-то редкое, то все равно проблемы неизбежны. Не с одним - так с другим. Портабельность и С++ - вещи малосовместимые, к сожалению.

авторупаковка в целое не обязана быть представлением адреса (вспомните про знаковые).
Насколько я понял, вы считаете, что если мы упакуем аддрес в signed, то его побайтовое предстваление будет другим. На i386 и amd64 это не так. побайтовые представления совпадают. И я уверен, что на большинстве архитектур - тоже.

Ниже прога, сделаная "на скору руку", как доказательство.

Код: plaintext
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.
30.
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

void printMem(void * addr){
    int i;
    unsigned char *cmem = (unsigned char *)addr;
    for(i=0; i<8; i++){
	printf("0x%x ", cmem[i] );
    }
    printf("\r\n");
}

int main(int argc, char ** argv){
    printf("sizeof(void*)=%lu\r\n", sizeof(void*) );
    printf("sizeof(long)=%lu\r\n", sizeof(long) );

    void * mem = malloc(300);
    long value = (long) mem;
    printMem(&mem);
    printMem(&value);

    mem= (void*) 0xffffffffffffffff; 
    value = (long) mem;
    printf("value=%li\r\n", value);

    printMem(&mem);
    printMem(&value);

}



На х64 вывод такой:

выводsizeof(void*)=8
sizeof(long)=8
0x10 0xa0 0xdd 0x1 0x0 0x0 0x0 0x0
0x10 0xa0 0xdd 0x1 0x0 0x0 0x0 0x0
value=-1
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff


Если вы будете ее тестить на х32 то у вас sizeof(void*) будет равно 4, и тогда вам надо распечатывать и сравнивать по 4 байта а не по 8, и возможно вместо long подставить что-то четырехбайтовое (если long таковым не будет).

само по себе хранение адреса в разобраном виде не опасно, если при этом где-то хранится и собраный адрес. А вот если собранный адрес не хранится нигде - то да, это опасно, и так делать не следует, если используешь эту либу. Но тут надо отметить, что такие махинации с адресом сами по себе довольно низкоуровневы, опасны и не портабельны. Если бы прога без этой либы теряла адрес на начало блока, а потом его "находила" через разрозненные части - я бы сказал, что это говнокод. Поэтому лучше такое вообще не использовать, а если используешь - можно временно отключать сборку мусора, например.
...
Рейтинг: 0 / 0
Поймать факт перезаписи
    #38092747
poselort
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Круто
...
Рейтинг: 0 / 0
123 сообщений из 123, показаны все 5 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Поймать факт перезаписи
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]