Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 18.11.2013
Сообщений: 16

Утечка памяти. Функция работы с изображениями выполняется в стороннем потоке.

23.12.2013, 15:30. Показов 1678. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток! Не могу решить проблему(( Есть функция работы с изображениями и выполняется эта функция в стороннем потоке...

Вот функция:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
String Images(int ind, String cm, int cm1)
{
    TStringList *kaka=new TStringList;
    Graphics::TBitmap *bmp1=new Graphics::TBitmap;
    Graphics::TBitmap *bmp=new Graphics::TBitmap;
    TJPEGImage *jpegi;
    TMemoryStream *stream ;
    TMemoryStream *buffer ;
    String link;
    TRect rect;
    cm.Delete(cm1,7);
    link=cm;
    link.Delete(1,cm1-1);
    int kl=link.Pos("}");
    link.Delete(kl,link.Length()-kl+1);
    cm.Delete(cm1,link.Length()+1);
    if(Form1->PathOfImageIn[ind]!=""){
      String cm2[100];
      widthImageOt[ind]=Form1->globalWidthPictureOt[ind];
      widthImageDo[ind]=Form1->globalWidthPictureDo[ind];
      compressOt[ind]=Form1->globalJPEGCompressOt[ind];
      compressDo[ind]=Form1->globalJPEGCompressDo[ind];
      widthCanvasOt[ind]=Form1->globalWidthCanvasOt[ind];
      widthCanvasDo[ind]=Form1->globalWidthCanvasDo[ind];
      heightCanvasOt[ind]=Form1->globalHeightCanvasOt[ind];
      heightCanvasDo[ind]=Form1->globalHeightCanvasDo[ind];
      moveXOt[ind]=Form1->globalMoveXOt[ind];
      moveXDo[ind]=Form1->globalMoveXDo[ind];
      moveYOt[ind]=Form1->globalMoveYOt[ind];
      moveYDo[ind]=Form1->globalMoveYDo[ind];
      rezatNaOt[ind]=Form1->globalCutPictureOt[ind];
      rezatNaDo[ind]=Form1->globalCutPictureDo[ind];
 
      int widthImage,compress,moveX,moveY,widthCanvas,heightCanvas,rezatNa;
      double W,H;
 
      moveX=moveXOt[ind]+rand()%(moveXDo[ind]-moveXOt[ind]+1);
      moveY=moveYOt[ind]+rand()%(moveYDo[ind]-moveYOt[ind]+1);
      rect.Left = moveX;
      rect.Top = moveY;
 
      widthCanvas=widthCanvasOt[ind]+rand()%(widthCanvasDo[ind]-widthCanvasOt[ind]+1);
      heightCanvas=heightCanvasOt[ind]+rand()%(heightCanvasDo[ind]-heightCanvasOt[ind]+1);
 
      bmp->LoadFromFile(Form1->PathOfImageIn[ind]);
      bmp->Dormant();
      bmp->FreeImage();
 
      W = bmp->Width;
      H = bmp->Height;
      widthImage=widthImageOt[ind]+rand()%(widthImageDo[ind]-widthImageOt[ind]+1);
      rect.Bottom = H / W * widthImage+moveY;
      rect.Right = widthImage+moveX;
 
      bmp1->PixelFormat=pf24bit;
      bmp1->HandleType=bmDDB;
      bmp1->Width=widthCanvas;
      bmp1->Height=heightCanvas;
      compress=compressOt[ind]+rand()%(compressDo[ind]-compressOt[ind]+1);
      StretchBlt(bmp1->Canvas->Handle,moveX,moveY,widthImage+moveX,H / W * widthImage+moveY,bmp->Canvas->Handle,0,0,W,H,SRCCOPY);
      bmp1->Dormant();
      bmp1->FreeImage();
 
      rezatNa=rezatNaOt[ind]+rand()%(rezatNaDo[ind]-rezatNaOt[ind]+1);
      int heightNaRazrez[200];
      heightNaRazrez[0]=-1;
      int ww[100],hh[100];
      String id[100];
      for(int i=0;i<rezatNa;i++){
        TRect SrcRect;
        TRect DstRect;
        stream = new TMemoryStream;
        buffer = new TMemoryStream;
        Graphics::TBitmap *bmp3=new Graphics::TBitmap;
        jpegi=new TJPEGImage();
        bmp3->PixelFormat=pf24bit;
        bmp3->HandleType=bmDIB;
        kaka->Clear();
        id[i]=IntToStr(_lrand()%1000000000)+"@"+IntToStr(_lrand()%100000000)+"-"+IntToStr(_lrand()%10000);
        heightNaRazrez[i+1]=heightNaRazrez[i]+1+heightCanvas/rezatNa+rand()%int(0.1*heightCanvas/rezatNa)-rand()%int(0.1*heightCanvas/rezatNa);
        if(i==rezatNa-1) heightNaRazrez[i+1]=heightCanvas;
        SrcRect = Rect(0, heightNaRazrez[i]+1, bmp1->Width, heightNaRazrez[i+1]);
        DstRect = Rect(0, 0, bmp1->Width, heightNaRazrez[i+1]-heightNaRazrez[i]-1);
        bmp3->Width = DstRect.Width();  ww[i]=bmp3->Width;
        bmp3->Height = DstRect.Height();  hh[i]=bmp3->Height;
 
        BitBlt(bmp3->Canvas->Handle,0,0,bmp3->Width,bmp3->Height,bmp1->Canvas->Handle,0,heightNaRazrez[i]+1,SRCCOPY);
 
        jpegi->CompressionQuality = compress;
        jpegi->Assign(bmp3);
        //jpegi->SaveToFile(ExtractFileDir(ParamStr(0))+"\\image"+IntToStr(i)+" "+IntToStr(_lrand()%100000)+".jpg");
        jpegi->SaveToStream(buffer);
        buffer->Position=0;
        stream->Position=0;
        Form1->IdEncoderMIME1->Encode(buffer,stream,buffer->Size+1);
        buffer->Position=0;
        stream->Position=0;
        kaka->LoadFromStream(stream);
        cm2[i]=kaka->Text;
        delete jpegi;
        delete bmp3;
        delete stream;
        delete buffer;
      };
      //тут формируется cm не важно как в принципе... просто складывается текст
 
      delete kaka;
 
    };
    delete bmp;
    delete bmp1;
    return cm;
}
На Windows 7 (на нескольких компах) работает отлично, а вот на 2003 или XP с одним потоком работает отлично, а вот если потоков больше, то через некоторое время вылазит ошибка "Недостаточно памяти для обработки команды" и такая ошибка при каждом следующем обращении к функции...
Памяти на 2003 4 Гб (так как 32 бита, то видно есстественно 3,24 примерно), виртуальной памяти 4Гб... Помогите плииз, идей нет уже, в интернете ничего не нашел полезного

Добавлено через 42 минуты
Ошибка ( по крайней мере первая ) вылазит после строк

Code
1
2
bmp1->Width=widthCanvas;//Эта строка присваивает значение
bmp1->Height=heightCanvas;//Эта строка уже не присваивает значение
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.12.2013, 15:30
Ответы с готовыми решениями:

Функция в стороннем потоке
Есть функция, как ее делать в параллель работе основной программы? pthread_create как правильно оформить? нужен пример!

Утечка памяти в потоке
Что я делаю не так procedure TMainThredRec.Execute; function BmpToMem(Bmp:TBitmap;var W,H:integer):pointer; var p: Pointer;...

Утечка памяти в потоке при многократной обработке TBitmap
Делфи7. Создаётся поток, где в цикле создаётся Bitmap1 (5МByte), который сравнивается c Bitmap2, далее Bitmap1.Free; Sleep(5000);...

19
 Аватар для Kabak
159 / 145 / 14
Регистрация: 03.02.2012
Сообщений: 788
Записей в блоге: 1
23.12.2013, 16:15
А если попробовать синхронизировать потоки ?
0
0 / 0 / 0
Регистрация: 18.11.2013
Сообщений: 16
24.12.2013, 10:14  [ТС]
Потоки синхронизированы мьютексами... По сути я и не понимаю ничего именно поэтому...

Code
1
2
HANDLE hMutex; //так объявляю мьютекс
hMutex=CreateMutex(NULL,false,NULL); //так создаю мьютекс
А так вызываю функцию, описанную выше


Code
1
2
3
WaitForSingleObject(hMutex,INFINITE);
Images(ind,cm,cm1);
ReleaseMutex(hMutex);
В принципе в данном случае при нескольких потоках функция все равно выполняется последовательно же... То есть одновременно два потока не могут войти в функцию... Так почему с одним потоком работает хорошо, а с несколькими плохо?(
0
 Аватар для Kabak
159 / 145 / 14
Регистрация: 03.02.2012
Сообщений: 788
Записей в блоге: 1
24.12.2013, 11:05
TStringList , TBitmap - визуальный компоненты. С визуальными компонентами можно работать в других потоках только через Synchronise( ИМЯ ВАШЕЙ ФУНКЦИИ ); - фактически выполнение будет в потоке программы.

Или Переписывайте функцию так, чтобы она не использовала в свём теле работу с VCL компонентами, или Synchronise( ИМЯ ВАШЕЙ ФУНКЦИИ );

Иначе глюки.
1
0 / 0 / 0
Регистрация: 18.11.2013
Сообщений: 16
24.12.2013, 11:08  [ТС]
Спасибо, а можете подсказать, что можно использовать вместо TBitmap в моем случае? HBITMAP ?
0
 Аватар для Kabak
159 / 145 / 14
Регистрация: 03.02.2012
Сообщений: 788
Записей в блоге: 1
24.12.2013, 11:16
Честно, не знаю про HBITMAP. Всё что угодно, но не VCL компонент. Может кто более продвинутый в этом ответит...
1
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
24.12.2013, 12:51
Цитата Сообщение от Kabak Посмотреть сообщение
TStringList , TBitmap - визуальный компоненты.
Очередная новость ?

Добавлено через 4 минуты
Цитата Сообщение от Kabak Посмотреть сообщение
А если попробовать синхронизировать потоки ?
При чем тут синхронизация, ясно же написали проблема в утечке памяти.

Вопрос только где.
Кроме того кода мало, и вообще не понятно что он доложен делать.

GibbonCho, Выложите все исходники, и укажите чего вы хотели добиться.
0
 Аватар для Kabak
159 / 145 / 14
Регистрация: 03.02.2012
Сообщений: 788
Записей в блоге: 1
24.12.2013, 13:01
Avazart, для вас цитата:
На Windows 7 (на нескольких компах) работает отлично, а вот на 2003 или XP с одним потоком работает отлично, а вот если потоков больше, то через некоторое время вылазит ошибка "Недостаточно памяти для обработки команды" и такая ошибка при каждом следующем обращении к функции...
Памяти на 2003 4 Гб (так как 32 бита, то видно есстественно 3,24 примерно), виртуальной памяти 4Гб... Помогите плииз, идей нет уже, в интернете ничего не нашел полезного
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33398 / 21508 / 8236
Регистрация: 22.10.2011
Сообщений: 36,906
Записей в блоге: 12
24.12.2013, 13:17
Что нового в этой цитате, и как она опровергает тот факт, что компоненту TBitmap не нужна синхронизация для работы с ним в доп. потоке (когда он в этом потоке и был создан)? Это не потомок TGraphicsControl, не потомок TWinControl, это даже не потомок TControl, а всего лишь наследник TPersistent... Так что никакого отношения к синхронизации в этом смысле утечка не имеет. Будет больше кода (хотя бы код, который можно запустить и убедиться в наличии утечки) - будет информация по предотвращению утечек. Гадать на кофейной гуще - неинтересно.
0
 Аватар для Kabak
159 / 145 / 14
Регистрация: 03.02.2012
Сообщений: 788
Записей в блоге: 1
24.12.2013, 13:38
Помолчу и дождусь истинной причины глюка.
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
24.12.2013, 13:47

Не по теме:

Цитата Сообщение от GibbonCho Посмотреть сообщение
На Windows 7 (на нескольких компах) работает отлично, а вот на 2003 или XP...
Я знаю, что не всегда легко на компьютере с XP увидеть по сети принтер, подключенный к компьютеру с семеркой. По крайней мере эта информация столь же полезна в данном случае как и рассуждение про синхронизацию.


Если б проблема была в синхронизации, то все бы падало с ошибкой доступа.

Цитата Сообщение от GibbonCho Посмотреть сообщение
через некоторое время вылазит ошибка
А ради хохмы - через сколько?

Цитата Сообщение от Avazart Посмотреть сообщение
Вопрос только где.
Да вот же:
Цитата Сообщение от GibbonCho Посмотреть сообщение
Ошибка ( по крайней мере первая ) вылазит после строк
C++
1
2
bmp1->Width=widthCanvas;//Эта строка присваивает значение
bmp1->Height=heightCanvas;//Эта строка уже не присваивает значение
Это вот эта строка:
C++
59
compress=compressOt[ind]+rand()%(compressDo[ind]-compressOt[ind]+1);
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
24.12.2013, 14:07
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Да вот же:
Вопрос где утечка, а не где ошибку выбивает.

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

Может там просто памяти не хватает на 1000 потоков и 1000 картинок ...
0
0 / 0 / 0
Регистрация: 18.11.2013
Сообщений: 16
25.12.2013, 08:25  [ТС]
Ок, Господа, проект большой, поэтому сейчас выдерну проблемный кусок, скомпилирую и выложу код)

Добавлено через 17 часов 36 минут
Выдернул кусок из проекта и засунул его в новый, в котором создаю 5 потоков и выполняю ту же функцию, но проблем на 2003 винде не обнаружил... Значит проблема не в самой функции... Выкладывать весь код проблемно ибо он большой очень, попробую поискать причину вне функции... Подскажите пожалуйста, могут ли проблемы возникать в связи с тем, что в проекте много форм (штук 10-12) и на формах много кнопочек и других компонентов среды C++ Builder? Читал о таком на некоторых форумах
0
 Аватар для Kabak
159 / 145 / 14
Регистрация: 03.02.2012
Сообщений: 788
Записей в блоге: 1
25.12.2013, 09:46
А может, при частом вызове какой-то функции или формы у вас постоянно происходит утечка памяти ? И к какому-то времени работы утекает столько , что больше "нет сил".
0
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
25.12.2013, 10:10
GibbonCho, утечка возможна только при некорректном использовании динамических объектов/переменных. Вряд ли проблема кроется в библиотеках билдера, и от количество форм и кнопочек тоже вряд ли зависит.
0
0 / 0 / 0
Регистрация: 18.11.2013
Сообщений: 16
25.12.2013, 11:30  [ТС]
Дело в том, что если не использовать именно эту функцию, то все хорошо и проблем нет... В моем проекте можно делать много разных операций, в основном с текстом... За каждую операцию отвечает своя функция... Я проверял все функции и все ок, но если использовать функцию Images(), то примерно после 400-500 вызовов при 5ти потоках вылазит подобная ошибка... Просмотрел весь проект, проверил правильно ли стоят мьютексы, проверил все ли динамически созданные объекты удаляются... Идей нет уже... С одной стороны так как минипроект работает, значит проблема где-то вне функции, с другой стороны если в большом проекте не использовать только эту функцию, то все работает хорошо...(
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.12.2013, 13:09
Цитата Сообщение от GibbonCho Посмотреть сообщение
Я проверял все функции и все ок
Ага я по этому куску кода уже представляю кучу строк чудо-кода в котором туча ошибок ...

Хотите гадать - на форум гадалок, не сюда ...
1
91 / 91 / 22
Регистрация: 02.07.2013
Сообщений: 332
25.12.2013, 14:35
GibbonCho, та ошибка, которая "вылазит" - это что за ошибка? Дословно? Системная? Или свой обработчик? Как именно определено, что она появляется после указанных строк? Шаманство с удалением старых объектников, ребилдом и прочим использовалось?
0
98 / 81 / 14
Регистрация: 26.07.2013
Сообщений: 594
25.12.2013, 15:13
- Некоторые новички почему-то с такой легкостью производят километры кода, не задумавшись
ни на секунду, как его оптимизировать и сделать надежней. Самое плохое, что они еще гордятся этим
километражом! Очень плохая черта. Отсюда и такие ошибки ...
0
 Аватар для Kabak
159 / 145 / 14
Регистрация: 03.02.2012
Сообщений: 788
Записей в блоге: 1
25.12.2013, 15:50
GibbonCho,

А почему вы *kaka созданный до if {} :
C++
1
TStringList *kaka=new TStringList;
удаляете в теле if ?

Переносите
C++
1
    delete kaka;
за тело if и попробуйте проект.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.12.2013, 15:50
Помогаю со студенческими работами здесь

Вектор, утечка памяти, функция создания и выделение памяти
Здравствуйте. Есть проблема. функция malloc выделяет память лишь в функции CreateVector(), и при выходе из нее указатель теряется. Или не...

Утечка памяти после работы программы
Подскажите пожалуйста, какими методами можно определить утечку памяти? Например, где то не сделал нужное Free. Какая то программа есть...

Утечка памяти программы работы с COM портом
Здравствуйте, недавно перешёл на C# попробовал простенький пример считывать показания датчика с Com порта, попробовал 3 или 4 примера, все...

Утечка памяти после долгой работы компьютера
Братцы нужна помощь, решил попробовать в этом разделе, т.к. в разделе &quot;оперативки&quot; не помогли.. вообщем если комп работает целый...

Работа с изображениями в новом потоке
Доброго времени суток! У меня возникла проблемка с потоками, а собственно, не выходит работать с изображениями в новом потоке. На...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru