Поиск:

Ответ в темуСоздание новой темы Создание опроса
> wincore.cpp 
:(
    Опции темы
mrgloom
Дата 9.9.2011, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



в режиме дебага когда идет запись в вектор
на функции 

SomeFuncPushTovec();

вылетает на 
Цитата

    CATCH_ALL(e)
    {
  lResult = AfxProcessWndProcException(e, &pThreadState->m_lastSentMsg);
  TRACE(traceAppMsg, 0, "Warning: Uncaught exception in WindowProc (returning %ld).\n",
    lResult);
  DELETE_EXCEPTION(e);
    }


по стэку вызовов понять ничего не удалось.

предполагаю, что что то связанное с ограничением на память (в е CMemoryException).

почему это происходит?
PM MAIL   Вверх
Earnest
Дата 9.9.2011, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Стек вызовов в момент отлова исключения рассматривать бесполезно. Нужно ловить исключение в момент генерации.
Во первых, нужно понять какой тип исключения. Это можно увидеть (в дебаге) в Output-окне. Там должно быть написано что-то вроде First chance exception at... Далее нужно в окне Debug-Exceptions включить перехват нужных типов исключений; можно сразу группу, а не поштучно. 
Если тип исключения понять не получается, попробуй C++ exceptions и Run-time (не помню. точно как называются - там где Access violation и т.д.)
Вот в момент генерации исключения смотри стек. 
Иногда бывает, что ты ловишь не первичное исключение, а "переизлученное". Тогда нужно еще поработать с окном перехвата исключений... и внимательно смотреть Output (найти самое первое исключение)



--------------------
...
PM   Вверх
mrgloom
Дата 12.9.2011, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



во время дебага нажал Ctrl + Alt +E
и поставил галочку напротив С++ Exeptions->CExeption
ну и дебагер остановился на том же месте CATCH_ALL(e)
тип исключения CMemoryExeption
в логе дебаг окна  Microsoft C++ exception: CMemoryException at memory location
я так и не понял как посмотреть из какого куска кода оно пришло.
PM MAIL   Вверх
Earnest
Дата 12.9.2011, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



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


--------------------
...
PM   Вверх
mrgloom
Дата 12.9.2011, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



надо было перед дебагом.

вообщем.
First-chance exception CMemoryException at memory location
bgheap.c
на строчке
/* do the allocation
             */
pvBlk = _heap_alloc_dbg_impl(nSize, nBlockUse, szFileName, nLine, errno_tmp);


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

хотя пробовал запускать откомпилированный экзешник на машине с 4Гб всю память не занимает, а вываливается примерно на 2Гб.

Это сообщение отредактировал(а) mrgloom - 12.9.2011, 16:27
PM MAIL   Вверх
Earnest
Дата 12.9.2011, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(mrgloom @  12.9.2011,  17:26 Найти цитируемый пост)
похоже просто не может выделить память в вектор 

Похоже???
Если ты реально ждал, что тебе 2 гб в хипе выделят, тебе срочно нужен ликбез - надо книжку какую-никакую прочесть, про виндоус, про память и т.д., Рихтера, например.  smile 



--------------------
...
PM   Вверх
mrgloom
Дата 13.9.2011, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



ну я так подозреваю что 2гб это предел для приложения в х32 системе? (хотя вроде тяжелые приложения как то расширяют это дело до 3Гб).

попробую под х64.

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



Upd: на х64 та же история (2GB per process) или я чего то делаю не то.
хотя на х64 всего 2Гб памяти так что может быть и в этом проблема.


Это сообщение отредактировал(а) mrgloom - 13.9.2011, 11:28
PM MAIL   Вверх
mrgloom
Дата 13.9.2011, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



пробовал этот метод скомпилировать с флагом /LARGEADDRESSAWARE
http://msdn.microsoft.com/en-us/library/wz223b1z

эффект тот же, хотя возможно из-за того, что х64 имеет 2Гб, но по идее есть еще и файл подкачки.
PM MAIL   Вверх
Earnest
Дата 13.9.2011, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



На 32-битной платформе процессу выделяется 4 гб виртуального адресного пространства. Больше не позволяет адресация. В это же адресное пространство отображаются все необходимые системные библиотеки, а также сам процесс. Сколько памяти есть физически в системе - не важно, это будет влиять только на скорость (разве что на диске не хватит места под своп или своп вообще отключен). Под хип остается то, что не занято стеком и прочими запросами на память. Причем хип может фрагментироваться. Так что рассчитывать на большой кусок не стоит.
Под 64-битной платформой памяти процессу должно выделяться по идее больше. Почему у тебя не получилось, не знаю. Разве что ты не компилировал под 64, а просто запустил 32-битное приложение.


--------------------
...
PM   Вверх
mrgloom
Дата 13.9.2011, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



нет я скомпилировал под х64(статическая линковка на выходе только 1 экзешник, флаг /LARGEADDRESSAWARE проставил насильно) (на системе х32 специально проверил экзешник не запустился) перенес на систему х64 и запустил там(только там 2Гб памяти) и начал смотреть что там происходит через vmmap примерно когда heap  занимал 1.8Гб , а полный размер ~2Гб  все начало свопиться и начались дикие тормоза, а потом все равно приложение вроде бы упало.

может нельзя выделять больше 2Гб непрерывной памяти? или на это нет ограничений?
PM MAIL   Вверх
Earnest
Дата 14.9.2011, 08:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(mrgloom @  13.9.2011,  18:34 Найти цитируемый пост)
может нельзя выделять больше 2Гб непрерывной памяти? или на это нет ограничений?

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


--------------------
...
PM   Вверх
mrgloom
Дата 14.9.2011, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



запустил на машине х64 с 4 гб, программа отъела 4Гб и сообщила, что ей не хватает памяти.

вообщем все работает, но почему то файл подкачки она кушать не хочет.  причем программа не падает, но и память не сбрасывает.
т.е. она кушает много памяти на ф-ии
add_many_items_to_vector()  
потом вылетает эксепшн на память и как дальше она себя ведёт\должна вести не очень понятно.

Добавлено через 4 минуты и 15 секунд
может возможно контролировать как то поведение программы на таких участках? или как то все время проверять с какой то периодичностью.
что то типа
Код

MEMORYSTATUSEX statex;//
statex.dwLength = sizeof (statex);//
GlobalMemoryStatusEx (&statex);//
if (statex.ullAvailVirtual)

PM MAIL   Вверх
Earnest
Дата 14.9.2011, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Может, проще не жрать столько памяти? smile 
Я за свою довольно долгую карьеру ни разу с таким проблемами не сталкивалась... 
Нельзя же программировать на абстрактной машине Тьюринга. 


--------------------
...
PM   Вверх
mrgloom
Дата 14.9.2011, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



заранее рассчитывалось, что приложение может есть много памяти.

аппетиты конечно сократятся, но хотелось бы уметь и обрабатывать такие ситуации нехватки памяти.
PM MAIL   Вверх
mrgloom
Дата 14.9.2011, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

скажем такое 
while(1)
{
     vec.push_back(item);
}


почитал тут http://users.msu.dubna.ru/~nefedov/c++course/p2-3.html
но там про new[],но я то работаю со стандартным вектором.
PM MAIL   Вверх
Earnest
Дата 14.9.2011, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



У тебя же генерируется CMemoryException? Вот его и лови.
Хотя странно, если std::vector, там другой тип исключения; точно не помню, тоже про память. Короче, выясни тип исключения и лови, в чем проблема?
Кстати, имей в виду. Вектор растет не по одному элементу а кусками. Причем, алгоритм определения размера прироста обычно довольно простой - типа удвоения текущего размера. Т.е. если тебе не хватит места всего под один элемент, вектор попытается раздуться вдвое. И может лопнуть.
Далее, перевыделение памяти происходит так: выделяем новый кусок, копируем туда старые значения, освобождаем старый. В результате - память фрагментируется! Т.е. возможен случай, когда память вроде есть, на 1000 мелких кусочков. Но вот на один большой (равный в сумме 1000 мелких) - фиг вам.
Короче, при больших аппетитах полагается сразу определиться с примерно нужным размером и заказать его сразу + небольшой запас, возможно.
Нельзя с большим вектором работать точно также как с маленьким.


--------------------
...
PM   Вверх
mrgloom
Дата 4.10.2011, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



если есть vector<vector<point>>
и я точно не знаю размер внутренних векторов и внешнего вектора,
 но например хочу под это дело выделить кусок памяти 2Гб, как это можно сделать?
PM MAIL   Вверх
Earnest
Дата 4.10.2011, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Никак, разве что свой аллокатор писать.
Либо дизайн пересмотри.
Например, можно сделать так: выделить большой пул для всех точек в виде vector<point>, а отдельную линию хранить как <начало-конец>.
Либо как-то еще упаковать, и прописать извлечение в виде объекта. Это требует довольно много кода, но при работе с большими массивами данных обойтись стандартными контейнерами не получится.
Например, у меня в программе векторные данные хранятся в виртуальной памяти (а не в хипе), в виде упакованных блоков, без всяких указателей. Для каждого слоя есть 2 параллельных пула: массив тэгов фиксированного размера (тэг - это структура, где записан тип объекта, экстент, размер, позиция во втором пуле и некоторые доп. данные). Второй пул содержит блоки разных размеров, где хранятся собственно данные (массив координат и т.д.). На оба пула сверху навернута поддержка списка свободных блоков. Все это закрыто в наборе классов, наружу торчат только ручки типа "Разместить объект", "Удалить", "Изменить". Объект извлекается в виде пары указателей (на тэг и данные), сверху навернуты объектные обертки. Причем их два типа (2 набора): "легкие" обертки, только для чтения, зато быстро создаваемые (например, прорисовка или поиск) и полновесные классы, для редактирования/создания.

Смысл примерно такой: упакованные данные занимают намного меньше места, меньше страдают от фрагментации, легко сериализуются (всем куском); 
для чтения (рисования) достаточно inline-оберток, которые преобразуют указатели к нужному типу и ничего не стоят. А полноценный объектный доступ нужен только при редактировании отдельных объектов. Тогда точки копируются в вектора (для полилиний), модифицируются, а потом снова упаковываются.


--------------------
...
PM   Вверх
mrgloom
Дата 4.10.2011, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



у меня проблема несколько в другом

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

"развернуть" все эти "заготовки" в реальные примитивы я не могу т.к. займет много памяти, приходится выцеплять частями, только те которые нужно.
в памяти я храню только описание объектов+ "куда их поставить".
я заранее простчитываю ограничивающие прямоугольники объектов и потом в цикле(когда надо отрисовать)
 накладываю на них преобразования(переместить, повернуть..) и проверяю 
1. Если ограничивающий прямоугольник пересекается или попадает в текущий видимый в программе прямоугольник.
2. если размер прямоугольника достаточно большой(чтобы не выводить маленькие).

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

вот код отрисовки, приходится еще выделять доп. память под временное хранилище.
vec это vector<vector<vector<point>>> , он содержит vector<vector<point>> т.е. список примитивов, которе приходят из разных тредов.
Код

//через Polypolyline
        HPEN redPen=CreatePen(PS_SOLID, 1, RGB(255,0,0));
        HGDIOBJ oldPen=SelectObject(dc,redPen);
        
        for (int k=0;k<vec.size();++k)
        {
            DWORD* lpPts=new DWORD[vec[k].size()];
            int n=0;
            for(int i=0;i<vec[k].size();++i)
            {
                lpPts[i]= vec[k][i].size();
                n+=vec[k][i].size();
            }
            CPoint* Pt= new CPoint[n];
            int c_i=0;
            for(int i=0;i<vec[k].size();++i)
            {
                for(int t=0;t<vec[k][i].size();++t)
                {
                    Pt[c_i].x= vec[k][i][t].point.x;
                    Pt[c_i].y= vec[k][i][t].point.y;
                    ++c_i;
                }
            }
            PolyPolyline(dc,Pt, lpPts, vec[k].size());
            delete[] Pt;
            delete[] lpPts;
        }




Это сообщение отредактировал(а) mrgloom - 4.10.2011, 14:45
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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