Узнать как был создан объект...
От: Tujh Голландия  
Дата: 30.06.08 10:35
Оценка:
Здравствуйте!
Вопрос достаточно необычный, можно ли определить как был сконструировал объект, статически или через вызов new ?
Или, как вариант, можно ли перегрузить оператор new что бы стало возможным это определить?
Заранее спасибо.

З.Ы. что подобный вопрос возник из-за ошибки проектирования я понимаю.
Re: Узнать как был создан объект...
От: Erop Россия  
Дата: 30.06.08 10:38
Оценка:
Здравствуйте, Tujh, Вы писали:

T>Вопрос достаточно необычный, можно ли определить как был сконструировал объект, статически или через вызов new ?

T>Или, как вариант, можно ли перегрузить оператор new что бы стало возможным это определить?
T>Заранее спасибо.

В общем случае нельзя. В частном -- сообщай подробности.

Кстати, если твой объект -- это поле другого объекта, созданного по new, то это какой из двух случаев?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Узнать как был создан объект...
От: Bell Россия  
Дата: 30.06.08 10:41
Оценка:
Здравствуйте, Tujh, Вы писали:

T>Здравствуйте!

T>Вопрос достаточно необычный, можно ли определить как был сконструировал объект, статически или через вызов new ?
В общем случае нет.

T>Или, как вариант, можно ли перегрузить оператор new что бы стало возможным это определить?

Можно перегрузить new / delete для класса, и каким-то образом вести список динамических аллокаций. Соотвественно имея объект и его адрес можно проверить, не содержится ли этот адрес в упомянутом списке.

При этом нужно помнить о многопоточности и о возможном смещении адресов при наследовании.
Любите книгу — источник знаний (с) М.Горький
Re: Узнать как был создан объект...
От: rg45 СССР  
Дата: 30.06.08 10:49
Оценка:
Здравствуйте, Tujh, Вы писали:

T>Здравствуйте!

T>Вопрос достаточно необычный, можно ли определить как был сконструировал объект, статически или через вызов new ?
T>Или, как вариант, можно ли перегрузить оператор new что бы стало возможным это определить?
T>Заранее спасибо.

T>З.Ы. что подобный вопрос возник из-за ошибки проектирования я понимаю.


Как вариант: можно запретить создавать объект статически.
... << RSDN@Home 1.2.0 alpha rev. 787>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: Узнать как был создан объект...
От: Erop Россия  
Дата: 30.06.08 11:05
Оценка: 1 (1)
Здравствуйте, rg45, Вы писали:

R>Как вариант: можно запретить создавать объект статически.

Мало того, можно не только запретить создавать объект не на куче, но ещё и завести такого его наследника, который повторяет всю функциональность + может создаваться статически, но не может на куче.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Узнать как был создан объект...
От: merk Россия  
Дата: 30.06.08 11:40
Оценка: -1
Здравствуйте, Tujh, Вы писали:

T>Здравствуйте!

T>Вопрос достаточно необычный, можно ли определить как был сконструировал объект, статически или через вызов new ?
T>Или, как вариант, можно ли перегрузить оператор new что бы стало возможным это определить?
T>Заранее спасибо.

T>З.Ы. что подобный вопрос возник из-за ошибки проектирования я понимаю.


доберитесь до хипменеджера, и узнайте диапазон адресов кучи.
ежли ваш поинтер унутре...можете не сомневаться...
Re[2]: Узнать как был создан объект...
От: Erop Россия  
Дата: 30.06.08 11:47
Оценка:
Здравствуйте, merk, Вы писали:

M>доберитесь до хипменеджера, и узнайте диапазон адресов кучи.

M>ежли ваш поинтер унутре...можете не сомневаться...

void foo()
{
    char buffer[sizeof( T )];
    T* p = new( buffer )T;
    // *p -- это на куче?
    p->~T();
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Узнать как был создан объект...
От: merk Россия  
Дата: 30.06.08 11:48
Оценка:
Здравствуйте, merk, Вы писали:

M>Здравствуйте, Tujh, Вы писали:


T>>Здравствуйте!

T>>Вопрос достаточно необычный, можно ли определить как был сконструировал объект, статически или через вызов new ?
T>>Или, как вариант, можно ли перегрузить оператор new что бы стало возможным это определить?
T>>Заранее спасибо.

T>>З.Ы. что подобный вопрос возник из-за ошибки проектирования я понимаю.


M>доберитесь до хипменеджера, и узнайте диапазон адресов кучи.

M>ежли ваш поинтер унутре...можете не сомневаться...

правда есть оказия, что треды будут свои стеки на куче делать. можно попутать со стековым обьектом треда.
но наше дело — наметить путя.
короче глобальные обьекты лежат в одном диапазоне адресов, куча в другом.
Re[3]: Узнать как был создан объект...
От: merk Россия  
Дата: 30.06.08 11:52
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, merk, Вы писали:


M>>доберитесь до хипменеджера, и узнайте диапазон адресов кучи.

M>>ежли ваш поинтер унутре...можете не сомневаться...

E>
void foo()
E>{
E>    char buffer[sizeof( T )];
E>    T* p = new( buffer )T;
E>    // *p -- это на куче?
    p->>~T();
E>}

экзотические new, собственные аллокаторы и создание обьекта на удаленной машине не рассматриваем.
кажется случай проще, и вовсе не тот.
здравствуйте, егор!
Re[4]: Узнать как был создан объект...
От: Erop Россия  
Дата: 30.06.08 11:56
Оценка:
Здравствуйте, merk, Вы писали:

M>экзотические new, собственные аллокаторы и создание обьекта на удаленной машине не рассматриваем.

А что экзотического в new размещения? Скажем std::vector ты пользуешься?

M>кажется случай проще, и вовсе не тот.

Мне кажется, что случай пока что не описан...
Указано на кривой дизвйн, но и только.

M>здравствуйте, егор!

И тебе не хворать. А что это ты по два раза здоолваешься?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Узнать как был создан объект...
От: Erop Россия  
Дата: 30.06.08 12:01
Оценка:
Здравствуйте, merk, Вы писали:

M>короче глобальные обьекты лежат в одном диапазоне адресов, куча в другом.

Тогда уж лучше хаккерить последовательно...
void OnStackDetector {
    bool IsConstructedOnStack() const { return isOnStack; }
    OnStackDetector() : isOnStack( test() ) {}
    OnStackDetector( const OnStackDetector& ) : isOnStack( test() ) {}
private:
    const bool isOnStack;

    bool test() const 
    {
        const char p* = (const char*) (const void*)this;
        return abs( p - (const char*)&p ) <= 4 * 1024; // константу подобрать :)
    }
};
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Узнать как был создан объект...
От: merk Россия  
Дата: 30.06.08 12:03
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, merk, Вы писали:


M>>экзотические new, собственные аллокаторы и создание обьекта на удаленной машине не рассматриваем.

E>А что экзотического в new размещения? Скажем std::vector ты пользуешься?

нет, а что?

M>>кажется случай проще, и вовсе не тот.

E>Мне кажется, что случай пока что не описан...
E>Указано на кривой дизвйн, но и только.
люди либо делитнули статический, либо недоделитили динамический. есть такое ощущение.

M>>здравствуйте, егор!

E>И тебе не хворать. А что это ты по два раза здоолваешься?
егор, это у вас какой-то эксепшн выскочил. для здорования у меня синглетон написан.
Re[3]: Узнать как был создан объект...
От: Tujh Голландия  
Дата: 30.06.08 12:10
Оценка:
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, rg45, Вы писали:
R>>Как вариант: можно запретить создавать объект статически.
E>Мало того, можно не только запретить создавать объект не на куче, но ещё и завести такого его наследника, который повторяет всю функциональность + может создаваться статически, но не может на куче.
А вот с этого места по подробнее можно ?
Хотелось бы что бы решение не было M$-specific, но в принципе и такое подойдет.

З.Ы. задача именно связана с многопоточностью.
Каждый класс thread при создании записывает указатель на себя в пул (который всегда статический), а при уничтожении удаляет.
В пуле реализован определенный функционал по управлению потоками. В частности сделана проверка, не допускающая старт потока, который был удален раньше, чем ОС передала управление в функцию этого потока.
В деструкторе пула проверяется существование потока, если поток не был удален, ему отсылается команда на удаление, делается выдержка времени и поток "убивается". Естественно, если я попытаюсь таким образом удалить статический объект — приложение "упадет" на уделении пула.
Пока не придумал, как можно архитектурно обойти эту ситуацию и нужна "заплатка" для того, что бы знать какие потоки нужно удалять из пула, а какие нельзя. Или же, как и предложили просто запретить создавать объекты потоков статически.
Re[6]: Узнать как был создан объект...
От: Erop Россия  
Дата: 30.06.08 12:13
Оценка:
Здравствуйте, merk, Вы писали:

E>>А что экзотического в new размещения? Скажем std::vector ты пользуешься?

M>нет, а что?
Ну если ты и никакого другого аналога не используешь, то ничего.
Другие используют. Перед тем, как начать советовать, а тем более спорить, мог бы и поинтересоваться...

M>люди либо делитнули статический, либо недоделитили динамический. есть такое ощущение.

Не наблюдаю ясной мысли
Грубо говоря я тебя так понял, что топикстартеру, по твоему мнению, хочется по объекту понять надо ли ему сказать delete или он сам как-то помрёт?
Так вот, хинт:
1) Не все объекты, которые попадают внутрь диапазона одресов кучи, можно удалять по delete
2) Не все объекты, которые попадают по адресам в стек или в статические данные, будут разрушены сами собой.

[offtop]
А что это ты по два раза здоолваешься?
M>егор, это у вас какой-то эксепшн выскочил. для здорования у меня синглетон написан.
Тут
Автор: merk
Дата: 30.06.08
прочитай...
[/offtop]
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Узнать как был создан объект...
От: merk Россия  
Дата: 30.06.08 12:16
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, merk, Вы писали:


M>>короче глобальные обьекты лежат в одном диапазоне адресов, куча в другом.

E>Тогда уж лучше хаккерить последовательно...
E>
void OnStackDetector {
E>    bool IsConstructedOnStack() const { return isOnStack; }
E>    OnStackDetector() : isOnStack( test() ) {}
E>    OnStackDetector( const OnStackDetector& ) : isOnStack( test() ) {}
E>private:
E>    const bool isOnStack;

E>    bool test() const 
E>    {
E>        const char p* = (const char*) (const void*)this;
E>        return abs( p - (const char*)&p ) <= 4 * 1024; // константу подобрать :)
E>    }
E>};

в теории нет ничего невозможного и например стековый обьект из другого треда может лежать далеко от текущего стека, то есть другого треда. так можно только смотреть только для стека своего треда.
строго говоря, опять же, залезши в дескриптор треда и покопамшись там, возможно можно найти, где-то, просто начало и длину его стека.
опять же зная, что стек растет в одну сторону, стековый обьект должен лежать где-то выше или ниже по адресам, чем адрес локальной переменной. это если обьект не из фрейма данной функции, а прямо или косвенно вызывающей.
Re[4]: Узнать как был создан объект...
От: Erop Россия  
Дата: 30.06.08 12:18
Оценка:
Здравствуйте, Tujh, Вы писали:

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


Сделай у потока закрытий деструктор + статический метод New, который собственно создаёт объект и регит в пуле, например, тоже.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Узнать как был создан объект...
От: Erop Россия  
Дата: 30.06.08 12:26
Оценка:
Здравствуйте, merk, Вы писали:

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

В теории есть даже невнимательные читатели чужого кода...

M>строго говоря, опять же, залезши в дескриптор треда и покопамшись там, возможно можно найти, где-то, просто начало и длину его стека.

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

Короче, пример кода набросай, да?

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

Ну так это ещё надо завнать куда он растёт... Для решения этой задачи это знание необязательно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Узнать как был создан объект...
От: merk Россия  
Дата: 30.06.08 12:29
Оценка: 4 (1) +1
Здравствуйте, Tujh, Вы писали:

T>Здравствуйте, Erop, Вы писали:

E>>Здравствуйте, rg45, Вы писали:
R>>>Как вариант: можно запретить создавать объект статически.
E>>Мало того, можно не только запретить создавать объект не на куче, но ещё и завести такого его наследника, который повторяет всю функциональность + может создаваться статически, но не может на куче.
T>А вот с этого места по подробнее можно ?
T>Хотелось бы что бы решение не было M$-specific, но в принципе и такое подойдет.

T>З.Ы. задача именно связана с многопоточностью.

T>Каждый класс thread при создании записывает указатель на себя в пул (который всегда статический), а при уничтожении удаляет.
T>В пуле реализован определенный функционал по управлению потоками. В частности сделана проверка, не допускающая старт потока, который был удален раньше, чем ОС передала управление в функцию этого потока.
T>В деструкторе пула проверяется существование потока, если поток не был удален, ему отсылается команда на удаление, делается выдержка времени и поток "убивается". Естественно, если я попытаюсь таким образом удалить статический объект — приложение "упадет" на уделении пула.
T>Пока не придумал, как можно архитектурно обойти эту ситуацию и нужна "заплатка" для того, что бы знать какие потоки нужно удалять из пула, а какие нельзя. Или же, как и предложили просто запретить создавать объекты потоков статически.

а как у вас тред добавляет сам себя в некий глобальный пул?
есть такая глубокораспространненая бага среди несистемных программеров, когда обьект в конструкторе сует сам себя в глобальный список. особенно это любят делать в базовом классе. пока тред один, все работает, как только есть много тредов, все падает случайным манером.
происходит следующее.
обьект в конструкторе себя в список сует,..и вдруг трык, треды переключаются, обьект недоконструирован, а в списке уже есть. другой тред его хвать, и все падает.
кароче. сначала полностью конструируете обьект и только потом суете в список. самозасовывание в конструкторах в списки, целиком и полностью противопоказано.
Re[5]: Узнать как был создан объект...
От: Erop Россия  
Дата: 30.06.08 12:33
Оценка:
Здравствуйте, merk, Вы писали:

M>кароче. сначала полностью конструируете обьект и только потом суете в список. самозасовывание в конструкторах в списки, целиком и полностью противопоказано.


По аналогичным причинам и удаление из деструктора базы тоже не особо корретно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Узнать как был создан объект...
От: merk Россия  
Дата: 30.06.08 12:47
Оценка: +1
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, merk, Вы писали:


M>>кароче. сначала полностью конструируете обьект и только потом суете в список. самозасовывание в конструкторах в списки, целиком и полностью противопоказано.


E>По аналогичным причинам и удаление из деструктора базы тоже не особо корретно...


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