Re[2]: Теория памяти
От: alsemm Россия  
Дата: 29.12.08 16:27
Оценка: +2
Здравствуйте, Roman Odaisky, Вы писали:

RO>2. Указатели, созданные new, надо освобождать с помощью delete, причем в том же потоке

Это еще с какого перепугу в том же потоке-то?

Алексей
Re[4]: Теория памяти
От: Аноним  
Дата: 30.12.08 03:14
Оценка: +1
RO>>>2. Указатели, созданные new, надо освобождать с помощью delete, причем в том же потоке.
CC>>Выделенное вроде как не по стандарту.
RO>В C++03 вообще никаких потоков нет, так что любые потоки — UB . RO>В зависимости от реализации, new-там-delete-здесь может быть безопасно, а может вызвать проблемы.
В стандарте — нету. В конкретных реализациях компиляторов и CRT — есть. В частности при использовании MSVC и включении MT-safe рантайма new/delete можно гарантированно без проблемно делать из разных потоков. Если же вы не включили правильнынй рантайм из каких то соображений — вы сами себе злобный Буратино.

RO>Да, и еще есть любители делать new в динамической библиотеке и delete в основном модуле, что может вызывать самые разные результаты в зависимости от фазы луны.

Это совершенно из другой оперы проблема.

RO>>>5. CreateThread — зло. И _beginthread(ex) — тоже зло, хотя и меньшее. boost::thread наше всё.

CC>>false.
CC>>Платим только за то, что используем. Если CRT не используем — то CreateThread наше всё.
RO>А если MS Windows не используем?
Говоря вашим же языком — буста в стандарте нету. А если буст не используем? Я не бустофоб, но всякое бывает. А кроме того буст не умеет (не умел?) юзать виндовый пул потоков.

RO>Кстати, в других ОС вообще есть такое недоразумение, как неиспользование libc?

libc это сущность относящаяся к ЯП и компилятору, ОС тут совсем не причем.
Теория памяти
От: Аноним  
Дата: 29.12.08 12:23
Оценка:
Всем привет.
Народ. Начал вот в С++ с динамической памятью кавыряться и сразу возник ряд вопросов. В книжке не нашел а рыться в сети — это долго

Вот например такой момент


cObject * object = new cObject;
......
object = NULL;


то что я потом обнуляю object может считаться альтернативой delete или же это чтото другое?
И такой момент


cObject * object = GetSomeObjectFromAnywhere();

object = NULL;


Вот здесь как я понимаю этот шаг оправдан. Или же все-таки нет?

И еще такой вопрсик
Захотел я создать поток вот так


..................
cObject * iObject = new cObject;
DWORD iThreadID;
HANDLE a_HThread;

a_HThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadFun, iObject, 0, & iThreadID);
..................

// Далее уже в потоковой функции

DWORD WINAPI ThreadFun(void * arguments)
{
    cObject * o = (cObject *) arguments;
        while(SomeCondition) {
        // Что-то там происходит и в итоге решил я цикл покинуть
        }

        delete s; // И вот тут я ловлю ошибку.


То есть получается, что я якобы второй раз удаляю этот объект (больше никаких оправданий винде найти не смог ).
Но вот проблема в том, что нигде-то я лапами её не убиваю. Может это происходит каким-то автоматом — или же что-то еще.
Как решение (помня что писал в начале топика) я сделал вместо delete s — s = NULL;
Ну вот чую что это вроде не то что я хочу и налицо memoryleak но вот что сделать правльно — падскажет может кто-нибудь??
Re: Теория памяти
От: rastoman  
Дата: 29.12.08 12:36
Оценка:
1. При присвоении указателю нуля, объект, на которой этот указатель ссылается, не разрушается. Надо явно вызвать delete для удаления.
2. см. п.1
3. Вместо CreateThread рекомендуется юзать _beginthreadex.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re: Теория памяти
От: Аноним  
Дата: 29.12.08 12:43
Оценка:
Здравствуйте, Аноним, Вы писали:
А>
А>    cObject * o = (cObject *) arguments;
А>        delete s; // И вот тут я ловлю ошибку.
А>


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

Что такое "s"?
Re[2]: Теория памяти
От: Аноним  
Дата: 29.12.08 12:47
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:

А>>
А>>    cObject * o = (cObject *) arguments;
А>>        delete s; // И вот тут я ловлю ошибку.
А>>


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

А>Что такое "s"?

s — это описка

на самом деле канечно
delete o;
Re[3]: Теория памяти
От: Аноним  
Дата: 29.12.08 13:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>Что такое "s"?


А>s — это описка


А>на самом деле канечно

А>delete o;

В таком случае, в приведенном коде ошибки не видно. А поток создается один раз?
Re[4]: Теория памяти
От: rastoman  
Дата: 29.12.08 13:24
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>В таком случае, в приведенном коде ошибки не видно. А поток создается один раз?

А почему бы под отладчиком не поставить break point в деструкторе сего объекта, что бы узнать, в какой момент времени он действительно уничтожается?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[5]: Теория памяти
От: Аноним  
Дата: 29.12.08 14:02
Оценка:
Здравствуйте, rastoman, Вы писали:

R>Здравствуйте, <Аноним>, Вы писали:


А>>В таком случае, в приведенном коде ошибки не видно. А поток создается один раз?

R>А почему бы под отладчиком не поставить break point в деструкторе сего объекта, что бы узнать, в какой момент времени он действительно уничтожается?
+1. Или на строке с delete. Конечно, если проблема действительно в повторном удалении.
Re: Теория памяти
От: Roman Odaisky Украина  
Дата: 29.12.08 16:20
Оценка:
Здравствуйте, Аноним, Вы писали:

А>падскажет может кто-нибудь??


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

Здесь основные принципы примерно такие:
1. В отличие от многих более других высокоуровневых языков, C++ следует принципу «платишь только за то, что используешь».
2. Указатели, созданные new, надо освобождать с помощью delete, причем в том же потоке. (Сюда же: а созданные new[] — с помощью delete[].)
3. C++ не может определить, нужен тебе объект или уже нет. Иные языки освобождают объект, когда последняя ссылка на него обнуляется, но C++ в силу п. 1 этого делать не может. Реализация такого механизма привела бы к расходам, которые нужны не всем.
4. Можно упростить себе жизнь с помощью std::unique_ptr (девичья фамилия — std::auto_ptr), boost::scoped_ptr, boost::shared_ptr.
5. CreateThread — зло. И _beginthread(ex) — тоже зло, хотя и меньшее. boost::thread наше всё.

А дальше в гугл.
До последнего не верил в пирамиду Лебедева.
Re[2]: Теория памяти
От: CreatorCray  
Дата: 29.12.08 16:50
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>2. Указатели, созданные new, надо освобождать с помощью delete, причем в том же потоке. (Сюда же: а созданные new[] — с помощью delete[].)

Выделенное вроде как не по стандарту.

RO>5. CreateThread — зло. И _beginthread(ex) — тоже зло, хотя и меньшее. boost::thread наше всё.

false.
Платим только за то, что используем. Если CRT не используем — то CreateThread наше всё.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[3]: Теория памяти
От: Roman Odaisky Украина  
Дата: 29.12.08 18:56
Оценка:
Здравствуйте, CreatorCray, Вы писали:

RO>>2. Указатели, созданные new, надо освобождать с помощью delete, причем в том же потоке.

CC>Выделенное вроде как не по стандарту.

В C++03 вообще никаких потоков нет, так что любые потоки — UB :-). В зависимости от реализации, new-там-delete-здесь может быть безопасно, а может вызвать проблемы.

Да, и еще есть любители делать new в динамической библиотеке и delete в основном модуле, что может вызывать самые разные результаты в зависимости от фазы луны.

RO>>5. CreateThread — зло. И _beginthread(ex) — тоже зло, хотя и меньшее. boost::thread наше всё.

CC>false.
CC>Платим только за то, что используем. Если CRT не используем — то CreateThread наше всё.

А если MS Windows не используем?

Кстати, в других ОС вообще есть такое недоразумение, как неиспользование libc?
До последнего не верил в пирамиду Лебедева.
Re: Теория памяти
От: Кодт Россия  
Дата: 30.12.08 01:53
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Народ. Начал вот в С++ с динамической памятью кавыряться и сразу возник ряд вопросов. В книжке не нашел а рыться в сети — это долго


Что за книжка? Народ должен знать антигероев в лицо.

А>
А>cObject * object = new cObject;
А>......
А>object = NULL;
А>

А>то что я потом обнуляю object может считаться альтернативой delete или же это чтото другое?

Альтернатива, но фиговая. Обнуление указателя — это просто обнуление указателя. Объекту от этого ни горячо ни холодно.
Вот если бы там был умный указатель (специальный объект, притворяющийся указателем), то он мог бы в операции присваивания выполнить удаление старого указуемого объекта или ещё что-нибудь полезное сделать.


А>И еще такой вопрсик

А>Захотел я создать поток вот так
А>
А>..................
А>cObject * iObject = new cObject;
А>DWORD iThreadID;
А>HANDLE a_HThread;

А>a_HThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadFun, iObject, 0, & iThreadID);

На будущее (а и на настоящее тоже). Всеми силами избегай реинтерпрет-каста указателей на функции. Стоит тебе ошибиться с количеством параметров или конвенцией вызова — и привет.
Так что выкинь к чёрту (LPTHREAD_START_ROUTINE), а если оно перестанет компилироваться — то иди исправлять ошибку в объявлении функции.
А>// Далее уже в потоковой функции
А>DWORD WINAPI ThreadFun(void * arguments)
А>{
А>    cObject * o = (cObject *) arguments;
А>        while(SomeCondition) {
А>        // Что-то там происходит и в итоге решил я цикл покинуть
А>        }

А>        delete s; // И вот тут я ловлю ошибку.
А>

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

Не надо искать оправданий винде, винда и так невиноватая, ты сам пришёл

Какая ошибка возникает?

Убедись, что
— ты включил multithreaded CRT (в опциях компилятора / свойствах проекта)?
— программа не успела выйти из main() / WinMain() до того, как подошла к точке delete s в этом потоке?

Для отладки: проверь, что адреса, передаваемый в поток и принятый как аргумент потока — равны.
Оттрассируй вызовы деструкторов.

Трудноуловимая, но очень кровавая ошибка — это расстрел памяти. Где-то в другом месте проехался с бензопилой по куче, а здесь на delete шов-то и разошёлся.


P.S.
С наступающим новым годом!
Желаю тебе встретить праздник, не нахлобучиваясь проблемами в твоей программе!
Перекуём баги на фичи!
Re[2]: Теория памяти
От: Аноним  
Дата: 30.12.08 07:06
Оценка:
Здравствуйте, rastoman, Вы писали:

R>1. При присвоении указателю нуля, объект, на которой этот указатель ссылается, не разрушается. Надо явно вызвать delete для удаления.

R>2. см. п.1
R>3. Вместо CreateThread рекомендуется юзать _beginthreadex.

Понял. Вот насчет п.3

Чем _beginthreadex лучше CreateThread??
Вроде работает ))
Re[2]: Теория памяти
От: Аноним  
Дата: 30.12.08 07:31
Оценка:
Здравствуйте, Кодт, Вы писали:

К>- ты включил multithreaded CRT (в опциях компилятора / свойствах проекта)?

Это то, что в MSVC называется ключом /MTd ?? Если так, то включено

К>- программа не успела выйти из main() / WinMain() до того, как подошла к точке delete s в этом потоке?

2. Точно нет.

К>Для отладки: проверь, что адреса, передаваемый в поток и принятый как аргумент потока — равны.

равны

К>Оттрассируй вызовы деструкторов.

патестил до конца))
нашел что AV зовет деструктор другого объекта который вызывается из LUA (да, её я тоже сюда прикрутил )

К>Трудноуловимая, но очень кровавая ошибка — это расстрел памяти. Где-то в другом месте проехался с бензопилой по куче, а здесь на delete шов-то и разошёлся.

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

К>P.S.

К>С наступающим новым годом!
К>Желаю тебе встретить праздник, не нахлобучиваясь проблемами в твоей программе!

Спос. Буит сделно!
И тебе того же
Re[4]: Теория памяти
От: CreatorCray  
Дата: 30.12.08 08:06
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Да, и еще есть любители делать new в динамической библиотеке и delete в основном модуле, что может вызывать самые разные результаты в зависимости от фазы луны.

Это implementation specific.

RO>>>5. CreateThread — зло. И _beginthread(ex) — тоже зло, хотя и меньшее. boost::thread наше всё.

CC>>false.
CC>>Платим только за то, что используем. Если CRT не используем — то CreateThread наше всё.

RO>А если MS Windows не используем?

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

RO>Кстати, в других ОС вообще есть такое недоразумение, как неиспользование libc?

Это всего лишь либа. Да, в ней есть некоторые вещи, которые компилер использует автоматически (типа поддержки int64 на 32-битной платформе, некоторые FPU хэлперы и т.п.), но никто не заставляет использовать все остальное. OS Native API к тому же предоставляет куда больший функционал чем убогие обертки libc.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[3]: Теория памяти
От: rastoman  
Дата: 30.12.08 09:02
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Чем _beginthreadex лучше CreateThread??

А>Вроде работает ))
"You must use _beginthread instead of CreateThread in C programs built with LIBCMT.LIB if you intend to call C run-time functions."
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[4]: Теория памяти
От: rastoman  
Дата: 30.12.08 09:02
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Да, и еще есть любители делать new в динамической библиотеке и delete в основном модуле, что может вызывать самые разные результаты в зависимости от фазы луны.

Если CRT прилинковано статически, то да. А если динамически, то можно выделять в одном модуле, а освобождать в другом.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[4]: Теория памяти
От: Аноним  
Дата: 30.12.08 10:41
Оценка:
Здравствуйте, rastoman, Вы писали:

R>Здравствуйте, <Аноним>, Вы писали:


А>>Чем _beginthreadex лучше CreateThread??

А>>Вроде работает ))
R>"You must use _beginthread instead of CreateThread in C programs built with LIBCMT.LIB if you intend to call C run-time functions."

А если у меня в проекте используется ключик
/NODEFAULTLIB:"LIBCMT.lib"
Т. к. оно конфликтует с кем-то, то мне можно дальше юзать CreateThread() или же всерно есть что-то плохое?
Re[3]: Теория памяти
От: CreatorCray  
Дата: 30.12.08 11:26
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Чем _beginthreadex лучше CreateThread??

Ничем не лучше. Внутри себя все равно вызывает CreateThread. Единственное отличие — она производит инициализацию CRT переменных в TLS потока. Эти переменные используются некоторыми функциями CRT и без подобной инициализации могут вести себя некорректно.
В общем сугубо implementation specific.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[5]: Теория памяти
От: CreatorCray  
Дата: 30.12.08 11:26
Оценка:
Здравствуйте, <Аноним>, Вы писали:

RO>>В C++03 вообще никаких потоков нет, так что любые потоки — UB . RO>В зависимости от реализации, new-там-delete-здесь может быть безопасно, а может вызвать проблемы.

А>В стандарте — нету. В конкретных реализациях компиляторов и CRT — есть. В частности при использовании MSVC и включении MT-safe рантайма new/delete можно гарантированно без проблемно делать из разных потоков. Если же вы не включили правильнынй рантайм из каких то соображений — вы сами себе злобный Буратино.
Т.е. это исключительно implementation specific грабли конкретных реализаций CRT.

RO>>Да, и еще есть любители делать new в динамической библиотеке и delete в основном модуле, что может вызывать самые разные результаты в зависимости от фазы луны.

А>Это совершенно из другой оперы проблема.
Это тоже строго implementation specific проблема CRT.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[6]: Теория памяти
От: Аноним  
Дата: 30.12.08 14:53
Оценка:
Здравствуйте, CreatorCray, Вы писали:

А>>В стандарте — нету. В конкретных реализациях компиляторов и CRT — есть. В частности при использовании MSVC и включении MT-safe рантайма new/delete можно гарантированно без проблемно делать из разных потоков. Если же вы не включили правильнынй рантайм из каких то соображений — вы сами себе злобный Буратино.

CC>Т.е. это исключительно implementation specific грабли конкретных реализаций CRT.

Ты можешь себе представить, что если когда-нибудь стандарт
установит правила на этот счет, то бы было явное ограничение new/delete в одном потоке?
Это бы противоречило уже сложившейся практике с распространненными компиляторами.
Re[5]: Теория памяти
От: degor Россия  
Дата: 02.01.09 13:45
Оценка:
Здравствуйте, rastoman, Вы писали:

R>Здравствуйте, Roman Odaisky, Вы писали:


RO>>Да, и еще есть любители делать new в динамической библиотеке и delete в основном модуле, что может вызывать самые разные результаты в зависимости от фазы луны.

R>Если CRT прилинковано статически, то да. А если динамически, то можно выделять в одном модуле, а освобождать в другом.
а если основной модуль и динамическая библиотека прилинкованы динамически, но к разным рантаймам?
Re: Теория памяти
От: Vinni-puh Россия  
Дата: 03.01.09 12:37
Оценка:
А>
А>..................
А>cObject * iObject = new cObject;
А>DWORD iThreadID;
А>HANDLE a_HThread;

А>a_HThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadFun, iObject, 0, & iThreadID);
А>..................

А>// Далее уже в потоковой функции

А>DWORD WINAPI ThreadFun(void * arguments)
А>{
А>    cObject * o = (cObject *) arguments;
А>        while(SomeCondition) {
А>        // Что-то там происходит и в итоге решил я цикл покинуть
А>        }

А>        delete s; // И вот тут я ловлю ошибку.
А>


Насколлько я понимаю, под CObjeсt подразумевается MFC-шный класс. Так вот, чтобы MFC как-то работала потоки нужно запускать AfxBeginThread().
Во-вторых MFC-шные классы не следует создавать в одном потоке, а уничтожать в другом. Вылетает на всяких ASSERT_VALID-ах внутри деструкторов. Так что рекомендую либо не наследовать объекты от MFC, либо уничтожать их в том же потоке, в котором они созданы.
Re[5]: Теория памяти
От: Vamp Россия  
Дата: 08.01.09 22:30
Оценка:
RO>>Кстати, в других ОС вообще есть такое недоразумение, как неиспользование libc?
CC>Это всего лишь либа. Да, в ней есть некоторые вещи, которые компилер использует автоматически (типа поддержки int64 на 32-битной платформе, некоторые FPU хэлперы и т.п.), но никто не заставляет использовать все остальное.

Действительно, почему-то от виндузятников постоянно слышно: КРТ не использую! Как слинковать программу, чтобы не использовала КРТ? Причина, вероятно, в том, что винда имеет некие полезные функции, которые традиционно входят в КРТ. Например, все богатство функций работы со строками. В той же солярке ничего такого нет.
Да здравствует мыло душистое и веревка пушистая.
Re[6]: Теория памяти
От: CreatorCray  
Дата: 09.01.09 09:23
Оценка:
Здравствуйте, Vamp, Вы писали:

RO>>>Кстати, в других ОС вообще есть такое недоразумение, как неиспользование libc?

CC>>Это всего лишь либа. Да, в ней есть некоторые вещи, которые компилер использует автоматически (типа поддержки int64 на 32-битной платформе, некоторые FPU хэлперы и т.п.), но никто не заставляет использовать все остальное.

V>Действительно, почему-то от виндузятников постоянно слышно: КРТ не использую!

V>Как слинковать программу, чтобы не использовала КРТ?

V>Причина, вероятно, в том, что винда имеет некие полезные функции, которые традиционно входят в КРТ.

Да хотяб работа с файлами: MMF, потоки, \\?\, sparced файлы, Junctions, Gather/Scatter, управление кэшированием — всего этого нет в CRT, да и быть не может.
ЗЫ: ДА! Я это всё использую.

V>Например, все богатство функций работы со строками.

Нафига CRT функции для строк если можно юзать STL-like строки. Оно как то поудобнее в разы.

Все что я использую из CRT (впрочем и то — косвенно) — это встраиваемые компилером функции преобразования int->float, работа с int64 на 32bit и т.п.
Остальное попросту не нужно.
Но это не значит что я выкорчевываю CRT и программ. Я просто не использую ничего, что вызывается явно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[7]: Теория памяти
От: Vamp Россия  
Дата: 09.01.09 15:50
Оценка:
CC>Да хотяб работа с файлами: MMF, потоки, \\?\, sparced файлы, Junctions, Gather/Scatter, управление кэшированием — всего этого нет в CRT, да и быть не может.
CC>ЗЫ: ДА! Я это всё использую.
Ну правильно, причем тут КРТ? Я же немного не о том.

CC>Нафига CRT функции для строк если можно юзать STL-like строки. Оно как то поудобнее в разы.

Зависит. Может потребоваться для работы со всякими третьими библиотеками, тем же API ОС и т.д.
Да здравствует мыло душистое и веревка пушистая.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.