Форум программистов, компьютерный форум CyberForum.ru

exception EEFFACE - C++

Восстановить пароль Регистрация
 
Алексей89
 Аватар для Алексей89
29 / 29 / 3
Регистрация: 19.02.2013
Сообщений: 107
23.02.2013, 17:19     exception EEFFACE #1
Есть такая проблема:
Работаю в Borland C++ Builder 6
В коде поочерёдно создаются и заполняются 2 массива по 198млн int значений
для обьявления массивов использую:
C++
1
2
static unsigned int *ResIn = new unsigned int [Kcmb+1]
static unsigned int *ResOut = new unsigned int [Kcmb+1];
на строке с обьявлением второго массива выдаёт ошибку: array.jpg
если ОК и запустить дальше выдаёт : array2.jpg
При меньших размерах массивов всё работат нормально
при попытке обьявить сразу 2 массива по 198млн. или массив двойного размера - те же самые ошибки.

Еесли записать один массив в файл - это, очевидно, снимет проблему.
Но дело в том, что в рамках моей задачи, первый массив имеет смысл аргументов (точек), а второй смысл функций (в точках).
Мне надо после заполнения массивов будет с ними работать, причём не по очереди, а винчестер в десятки раз срежет быстродействие, а программа и так долгая.

Смотрел в гугле: такие ошибки (EEFFACE) на пример, на делфи связывают с конфликтом ОС
Пробовал запускать на компе с 8 Гб оперативы, на Windows7x64;
и на компе 4 Гб оперативы WindowsXP sp3 X32;
- непомогло

Вот я и подумал, может всё таки, есть способ не записывать в файл массив, использовать класс какой-то, или настройки...
Посоветуйте что-нибудь пожалуйста.
Миниатюры
exception EEFFACE  
Изображения
 
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.02.2013, 17:19     exception EEFFACE
Посмотрите здесь:

Unhandled exception C++
exception и cerr C++
Exception C++
C++ exception
Не ловит exception C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
25.02.2013, 09:59     exception EEFFACE #2
Не знаю, можно ли создать в Builder6 64-битное приложение. Но дело, вероятно в ограничении для 32-битных программ. Почитайте например тут.
А зачем Вам такие большие массивы?
lemegeton
 Аватар для lemegeton
2910 / 1339 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
25.02.2013, 13:28     exception EEFFACE #3
Исключение bad_alloc возникает, когда в ответ на запрос выделить память система не может её выделить.
Наиболее вероятно, что дело в разрядности системы. 32-битному приложению доступно всего 2Гб ОЗУ. Попробуйте собрать 64-битную версию приложения и проверить на ней.

Я так понимаю, что у вас обработка изображения или видео. Альтернативно можно попробовать разбить обработку входящих данных на несколько блоков или попробовать изменить алгоритм.
Алексей89
 Аватар для Алексей89
29 / 29 / 3
Регистрация: 19.02.2013
Сообщений: 107
25.02.2013, 21:44  [ТС]     exception EEFFACE #4
Цитата Сообщение от Tulosba Посмотреть сообщение
Не знаю, можно ли создать в Builder6 64-битное приложение. Но дело, вероятно в ограничении для 32-битных программ. Почитайте например тут.
А зачем Вам такие большие массивы?
Большое спасибо, похоже, это именно то что мне нужно. Но ввиду того что я программированию обучался в рамках общего курса в Вузе, (а так вообще я радиофизик) у меня назрел ряд вопросов по тому что я прочитал /*тут*/
1.
Стековые данные. На них память выделяется при заходе в процедуру и освобождается при её завершении. Максимальный размер стека программы составляет 1 GB и для 32-битных, и для 64-битных приложений. (Размер стека задаётся линковщиком и по умолчанию составляет 1 MB)
На сколько мне известно из книжек по контроллерам, Стек - это память, цель которой хранить адрес строки возврата в программе, при уходе программы в функцию или при работе цикла.
"Стековые данные", это тоже самое что и стек?
2.
У 32-битного приложения запущенного в 32-битной Windows суммарный размер всех перечисленных типов данных не должен превышать 2 GB. (Практически ограничение равно 1.75GB из-за требований к памяти самой операционной системы) 32-битная программа, собранная с ключом /LARGEADDRESSAWARE:YES может выделять до 3-х гигабайт памяти, если 32-битная операционная система Windows запущена с ключом /3gb. Эта же 32-битная программа, запущенная на 64-битной системе, может выделить почти 4 GB памяти (на практике около 3.5 GB).
что есть в этом контексте "ключ" и как узнать какой он у меня?
3. Подсчитаем память для двух динамических массивов, которые мне нужны:
198 086 316(кол-во элементов)*4(байта на 1integer) = 792 345 264 байт или 755,64 МегаБайт
для двух массивов соответственно: 1511,28 Мегабайт.
Выходит до 2 Гигабайт недотягивает
Кроме того всё вместе на момент ошибки занимает 781916 Кб = 763,59 МегаБайт (По диспетчеру задач)
Даже если (с запасом) удвоить: 763,59*2 = 1527,18МегаБайт
- Всё равно меньше 1,75 Гб, о которых говорится /*тут*/
Поэтому вопрос такой:
Массив определён как static внутри блока кнопочки на форме, а глобально обьявлен только указатель на него
Сам массив в этом случае, чисто случайно, не является "стековыми данными"?
И вообще как принято правильно обьявлять глобальные динамические массивы до того как известен их будущий размер?

К слову о размерах массивов - Это не изображения, массивы одномерные они касаются научных изысканий моего руководителя. После заполнения они будут обрабатываться, возможно аппроксимироваться, а для этого при каждой итерации аппроксимирующего алгоритма будет считаться среднеквадратичное отклонение (функция каждой точки). поэтому мне очень желательно не записывать на винчестер эти массивы.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
25.02.2013, 22:26     exception EEFFACE #5
Цитата Сообщение от Алексей89 Посмотреть сообщение
"Стековые данные", это тоже самое что и стек?
Стековые данные - это данные, помещенные в стек. Про стек можете почитать в википедии (Аппаратный стек).
Цитата Сообщение от Алексей89 Посмотреть сообщение
что есть в этом контексте "ключ" и как узнать какой он у меня?
Есть ключ для программы (/LARGEADDRESSAWARE:YES), а есть ключ для ОС (/3gb).
По умолчанию, ни тот, ни другой не заданы.
Цитата Сообщение от Алексей89 Посмотреть сообщение
Подсчитаем память для двух динамических массивов, которые мне нужны
Фактически ограничение на разных системах могут отличаться. Поэтому, самый простой способ, это не заморачиваться с описанными выше ключами, а сделать полноценное 64-битное приложение (если BCB6 позволяет это). Или отказаться от BCB6 в пользу более новых версий, а может быть даже выбрать MS VisualStudio.

Цитата Сообщение от Алексей89 Посмотреть сообщение
Сам массив в этом случае, чисто случайно, не является "стековыми данными"?
Всё то, что задано через оператор new, находится в динамической памяти (куче) и не является стековыми данными.
Цитата Сообщение от Алексей89 Посмотреть сообщение
как принято правильно обьявлять глобальные динамические массивы до того как известен их будущий размер?
Глобальные данные лучше вообще не использовать. Но если уж используются, сделать например глобальный указатель, а память выделить когда станет известно, сколько ее надо. Например:
C++
1
2
3
4
5
int* ptr;
void SomeFunction()
{
   ptr = new int[ 100500 ];
}
Если перейти на 64-битное приложение проблематично, можно, я думаю, оптимизировать Вашу задачу, чтобы съедала меньше памяти. Но для этого уже нужно знать больше подробностей о ней.
Алексей89
 Аватар для Алексей89
29 / 29 / 3
Регистрация: 19.02.2013
Сообщений: 107
26.02.2013, 20:42  [ТС]     exception EEFFACE #6
Привожу проблемный блок:
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
#include <math.hpp>
#include <iostream.h>
#include <fstream.h>
        #include <dstring.h>
        # include <alloc.h>
        # include <stdlib.h>
#include "UnitMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TQAtab *QAtab;
 unsigned int *PResIn=0, *PResOut=0;  //Указателb на целевые массивы
 unsigned int Kcmb;
 int Kstep, cntr, Rin, Rout, CSin, CCSout;
//---------------------------------------------------------------------------
__fastcall TQAtab::TQAtab(TComponent* Owner)
        : TForm(Owner)
{
 
}
 
//---------------------------------------------------------------------------
void __fastcall TQAtab::ButtonStartClick(TObject *Sender)
{
int i, j, AddCS, Incntr;
extern int Kstep, Rin, Rout, CSin, CCSout, cntr;
extern unsigned int *PResIn, *PResOut;
extern unsigned int Kcmb;
Kcmb=EditKcmb->Text.ToInt();
Kcmb=Kcmb-1;                    //т.к. счёт идёт с 0
Kstep=EditKstep->Text.ToInt();
int t, L;
L=LogN(Rin,4294967295)+1;              
unsigned int *Rdgr32In = new unsigned int[L+1]; //Временный массив используется для наполнения целевого (большого) массива 
...
 
static unsigned int *ResIn = new unsigned int [Kcmb+1];     //Инициализация массива
PResIn=ResIn;                       //Взятие адреса целевого массива глобальным указателем *PResIn
...
delete []Rdgr32In;
...
unsigned int *Rdgr32Out = new unsigned int[L+1]; //Временный массив используется для наполнения целевого (большого) массива 
...
static unsigned int *ResOut = new unsigned int [Kcmb+1];     //Инициализация массива
PResOut=ResOut;                         //Взятие адреса целевого массива глобальным указателем *PResOut
...
}
Фактически ограничение на разных системах могут отличаться. Поэтому, самый простой способ, это не заморачиваться с описанными выше ключами, а сделать полноценное 64-битное приложение (если BCB6 позволяет это). Или отказаться от BCB6 в пользу более новых версий, а может быть даже выбрать MS VisualStudio.
Я раньше чучуть писал на фортране и на матлабе, но когда у меня встал вопрос о быстродействии, Все кто мог дать мне совет твердили "С++". Borland 6 я выбрал тоже по совету знакомого, т.к. он довольно старый и качественно взломаный, что сводит к минимуму возможность некорректной работы каких-то функций. В перспективе, конечно надо бы переходить на что-нибудь посовременнее, но сейчас мне нужно доделать программу руководителю, а большая её часть уже написана на Borland c++ 6
Эту же программу с этим же билдером я принёс к другу на Windows7x64, поставил там билдер, запустил программу и с ней произошло всё то-же что и у меня.
Я правда не знаю, то что я поставил билдер на 64-х разрядную ОС означает ли, что програма работала в режиме Win64

В любом случае проблема наверняка типичная и её наверняка решили ещё когда BCB6 был в моде.
Вот например, пока искал в гугле про ключи нашёл такой блог. Интересным мне показался Миф№4, здесь говорится о "выделении памяти без проецирования на адресное пространство" но (правда на делфи).
Здесь надо сказать, что при создании этой темы я опустил важную деталь: Размер двух целевых массивов определяется единожды, после заполнения эти массивы формально можно считать не динамическими а статическими.
Вот я и подумал, раз уж у меня проблема со 2-м массивом (а их в перспективе будет не меньше 3-х), то имеет смысл записать его в файл, а потом спроецировать его в оперативную память.

Если это верный способ то подскажите, пожалуйста, как это правильно делается?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.02.2013, 22:10     exception EEFFACE
Еще ссылки по теме:

C++ Обработка exception
C++ exception C++
First chance exception at $77ADB09E. Exception class EAccessViolation with message 'Access Violation'. Process C++

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

Или воспользуйтесь поиском по форуму:
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
26.02.2013, 22:10     exception EEFFACE #7
Цитата Сообщение от Алексей89 Посмотреть сообщение
Borland 6 я выбрал тоже по совету знакомого, т.к. он довольно старый и качественно взломаный
С этим сейчас проблем нет. Можете попробовать портировать свой проект под свежую версию Builder. И там уже собрать в 64-битном режиме. Сам не пользовался, но написано, что он там есть.
Цитата Сообщение от Алексей89 Посмотреть сообщение
то что я поставил билдер на 64-х разрядную ОС означает ли, что програма работала в режиме Win64
Нет. Программа должна быть собрана в соответствующем режиме.
Цитата Сообщение от Алексей89 Посмотреть сообщение
Если это верный способ то подскажите, пожалуйста, как это правильно делается?
У меня никогда не стояло задачи впихнуть в 32-битное приложение возможность адресовать такие большие объёмы как у Вас. Поэтому повторюсь: самый простой способ - это собрать в 64-битном режиме. Правда тогда на 32-бит винде уже не запустится.
Yandex
Объявления
26.02.2013, 22:10     exception EEFFACE
Ответ Создать тему
Опции темы

Текущее время: 07:55. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru