Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TMemoryStream, Access Violation 
V
    Опции темы
Diabolus
Дата 12.6.2007, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 12.6.2007

Репутация: нет
Всего: нет



Задача - пересылка изображения через сокеты. Здесь я решил использовать TMemoryStream, но решил сначала дописать программу, а потом исправлять небольшие баги. Одним из таких багов был как раз тот, о котором пишу сейчас, и из-за которого пришлось переписать половину программы, что, правда, тоже результата никакого не дало :(
А теперь ближе к делу smile
Создаётся рисунок TJPEGImage, он сохраняется в TMemoryStream, которая, в свою очередь, пересылается по TServerSocket'у, принимается на другой стороне, и там уже порядок действий обратный.

Глобальные переменные
Код

TMemoryStream *shit = new TMemoryStream();
TJPEGImage* jpg = new TJPEGImage;


Код
Код

  shit->Position=0;
  jpg->SaveToStream(shit);
  Socket->SendText(shit->Size);


В этих строках, судя по всему, и заключается проблема. Точнее сказать, ошибка появляется при попытке выполения сего кода. Причём при первом выполнении всё нормально, проблема возникает на второй попытке.
Методом научного тыка исправить пробовал многими способами, но ошибка появляется и всё тут.
Изначально, когда исправлял баги напильником для создания каркаса программы, каждый раз заново создавал TMemoryStream, но освобождать память, отведённую под неё, опять же не удавалось, вследствие чего программа кушала оперативку пока не лопнет :(
Думал сначала, что дело там во Write (дописывал 3 байта в мемористрим для обнаружения конца оной на другой стороне), после чего стал отсылать размер в отдельном пакете. Но всё же после первого раза не работает. Выдаёт, как говорилось выше, AV.
Прошу совета по устранению ошибки. Заранее спасибо.

Это сообщение отредактировал(а) Diabolus - 12.5.2010, 09:47
PM MAIL   Вверх
_hunter
Дата 13.6.2007, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 24
Всего: 98



дык: где именно ошибка (в какой строке). что значит "Глобальные переменные"? (где этот кусок расположен?)


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Diabolus
Дата 13.6.2007, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 12.6.2007

Репутация: нет
Всего: нет



Ошибка появляется при выполнении следующей строки на втором круге выполнения программы:
Код

jpg->SaveToStream(shit);

Ну а расматриваемые переменные у меня обозначены перед всеми процедурами (т.е. вверху) в Unit1.cpp, ну и использоваться могут из всей программы. Если объявить TMemoryStream *shit в самой рассматриваемой процедуре, то, как говорилось выше, всё работает, но ест оперативку. Всяческие shit->Free() вызывают опять же ошибки :(
PM MAIL   Вверх
_hunter
Дата 13.6.2007, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 24
Всего: 98



Цитата(Diabolus @  13.6.2007,  13:24 Найти цитируемый пост)
Ошибка появляется при выполнении следующей строки на втором круге выполнения программы:

смотрим дальше. если SaveToStream() выполнить на вновь созданном потоке (а не использовать старый) лшибка останется?

Цитата(Diabolus @  13.6.2007,  13:24 Найти цитируемый пост)
Ну а расматриваемые переменные у меня обозначены перед всеми процедурами (т.е. вверху) 

и "= new TMemoryStream();" написанно там же?..




--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Diabolus
Дата 13.6.2007, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 12.6.2007

Репутация: нет
Всего: нет



Цитата
смотрим дальше. если SaveToStream() выполнить на вновь созданном потоке (а не использовать старый) лшибка останется?

Нет, ошибки не будет, но оперативка съедается безвозвратно.
Цитата
и "= new TMemoryStream();" написанно там же?..

Да.
PM MAIL   Вверх
_hunter
Дата 13.6.2007, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 24
Всего: 98



Цитата(Diabolus @  13.6.2007,  13:53 Найти цитируемый пост)
Нет, ошибки не будет

значит чтобы не было ошибки -- нужно TMemoryStream создавать перед каждым SaveToStream().

Цитата(Diabolus @  13.6.2007,  13:53 Найти цитируемый пост)
но оперативка съедается безвозвратно

ну так ресурсы освобождать нужно хоть иногда...


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Vyacheslav
Дата 13.6.2007, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Цитата(Diabolus @  13.6.2007,  13:53 Найти цитируемый пост)
Нет, ошибки не будет, но оперативка съедается безвозвратно

Как это определяли. Небось Task Manager ?
Читае help по SendStream
Цитата

Note:    The Stream passed as a parameter to SendStream becomes “owned” by the windows socket object.  The Windows socket object frees the stream when it is finished with it.  Do not attempt to free the stream after it has been passed as a parameter.

и переводим smile
Цитата

Замечание.  Stream использованный как парараметр в SendStream становится "принадлежащим" объекту window socket. Windows socket отсвобождает stream когда закончит с ним.  Не делайте  попытку освободить stream после того, как использовали его в качестве  параметра.

Если я правильно понял, то к моменту второго использования socket уничтожает Stream. А Вы пытаетесь использовать уже разрушенный объект





--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Diabolus
Дата 13.6.2007, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 12.6.2007

Репутация: нет
Всего: нет



Цитата
ну так ресурсы освобождать нужно хоть иногда...

Цитата
Изначально, когда исправлял баги напильником для создания каркаса программы, каждый раз заново создавал TMemoryStream, но освобождать память, отведённую под неё, опять же не удавалось, вследствие чего программа кушала оперативку пока не лопнет :(

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

void __fastcall Tmain::ssClientRead(TObject *Sender, TCustomWinSocket *Socket) {
...
TMemoryStream *shit;
...
} else if(com=="GetSize") {
shit = new TMemoryStream();
...
} else if(com=="GetScreen") {
  shit->Position=0;      // здесь получаем AV
  Socket->SendStream(shit);
}
...
}

Не пойму, откуда все эти AV при использовании TMemoryStream берутся =\

Добавлено через 2 минуты и 41 секунду
Vyacheslav, спасибо большое, действительно похоже на то smile
Но как же в таком случае контролировать занимаемую память? Неужели каждый раз переподключаться сокетом? =\
PM MAIL   Вверх
Vyacheslav
Дата 13.6.2007, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



Да у Вас либо утечек нет и все это домыслы по  результам работы Task Manager, либо Вы не удаляете что то другое. Например , это 
Код

TJPEGImage* jpg = new TJPEGImage;




--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Diabolus
Дата 13.6.2007, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 12.6.2007

Репутация: нет
Всего: нет



Ещё раз спасибо, сейчас попробую всё сделать наконец как надо :)
upd: дописал всё, всем спасибо :)

Это сообщение отредактировал(а) Diabolus - 13.6.2007, 18:50
PM MAIL   Вверх
Diabolus
Дата 16.6.2007, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 12.6.2007

Репутация: нет
Всего: нет



Сюда же напишу, т.к. ни у себя, ни в сети не нашёл чудо-хелп с таким описанием пересылки TMemoryStream через сокет, сам BCB у меня тоже без хелпа :( Искал по запросу "bcb6.hlp". Если есть у кого-нибудь, то подкиньте пожалуйста, очень бы пригодилось :)

Это сообщение отредактировал(а) Diabolus - 16.6.2007, 11:17
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.1106 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.