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

Один большой динамический массив вместо нескольких меньшего размера - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
ken_guru
0 / 0 / 0
Регистрация: 18.10.2011
Сообщений: 13
10.02.2013, 03:19     Один большой динамический массив вместо нескольких меньшего размера #1
Уважаемые форумчане,

Прошу помочь советом.

Интересует ответы на вопросы: Возможно ли? Если да, то как реализовать?

Предисловие:
Не так давно начал заниматься в вузе моделированием (трассировка частиц в поле). До настоящего момента пользовался статическими массивами и не знал проблем. Однако в процессе написания программы количество задаваемых массивов безбожно увеличилось и мелкомягкий стал ругаться на переполнение стека.
Погуглил - пришел к выводу, что надо переходить на динамические массивы.
Попробовал... заменил все двухмерные статические массивы на двухмерные динамические - теперь постоянно возникает утечка памяти (проверял места где происходит инициализация и освобождение памяти сотню раз - все равно утечка памяти)
В вузе насоветовали избавиться от двухмерных динамических массивов, а лучше вообще от нескольких массивов - вместо этого использовать один большой одномерный динамический массив - типа так можно избавиться от проблем с утечкой.

Суть:
Создать один большой динамический массив - дело секундное. Но возникает вопрос - как потом к нему обращаться так чтобы не запутаться ?
Да конечно можно использовать простую формулу типа А[i*N+j] для одномерного массива вместо A[i][j] для двухмерного. Но как быть если массивов штук 20?

Есть ли какой нибудь способ инициализации некой структуры, которая будут являться указателем на некоторую часть большого динамического массива?
т.е. что-то вроде такого:

Некая структура = А[i*N+j] для значений i и j от 0 до некоторого значения (например от 100 до 100)
Некая структура №2 = А[i*N+j + 10000] - указатели на другую часть большого массива
и т.д.

Возможно ли?

Заранее огромное спасибо!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.02.2013, 03:19     Один большой динамический массив вместо нескольких меньшего размера
Посмотрите здесь:

динамический массив структур qwer заданного пользователем размера C++
C++ Нужно последовательно собрать их в один динамический массив.
C++ Вместо вывода в stdout, сохранить числа в динамический массив
динамический массив произвольного размера C++
Двумерный динамический массив размера NxM C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
abit
 Аватар для abit
260 / 259 / 33
Регистрация: 03.02.2013
Сообщений: 709
10.02.2013, 03:25     Один большой динамический массив вместо нескольких меньшего размера #2
я дважды сбился с мысли, пока читал вашу трогательную историю...
ответ да, возможно

только мне не понятно чем вас не устраивают контейнеры? чего вы возитесь с массивами
ken_guru
0 / 0 / 0
Регистрация: 18.10.2011
Сообщений: 13
10.02.2013, 03:37  [ТС]     Один большой динамический массив вместо нескольких меньшего размера #3
С краткими описаниями у меня тяжко... :-)

Но ведь указали могут указывать только на один элемент. Т.е. для некого массива в N элементов придется создавать N указателей. Или я ошибаюсь?

Насколько я могу судить исходя из тех немногочисленных знаний, которые у меня есть - под вектор (контейнер) также выделяется динамически память и главное преимуществе перед динамическими массивами - можно изменять количество элементов во время выполнения в зависимости от нужд.
Но у меня нет такой необходимости. Грубо говоря у меня есть двухмерная сетка заданного размера и нужны соответствующие структуры, которые будут содержать определенную информацию (плотности, токи, поля и т.д.) в каждом из узлов сетки до следующей итерации (следующего полета частиц).
abit
 Аватар для abit
260 / 259 / 33
Регистрация: 03.02.2013
Сообщений: 709
10.02.2013, 03:39     Один большой динамический массив вместо нескольких меньшего размера #4
по поводу вашей "некой структуры"
воспользуйтесь свойствами неконстантых указателей

C++
1
2
3
4
5
6
7
8
int*a;
    int *p;
    a = new int (10);
    a[5]=4;
    p = (a+5);
    cout << p[0];
    cout<<endl;
    delete[] a;
здесь p[0] вернёт a[5], понятно, что p[1] вернёт a[6] и т.д.

если говорить о векторе (хотя это не единственный контейнер), то у него куда больше прекрасных свойств, чем вы указали, к тому же не стоит думать о delete, так что описанных вами проблем не будет
ken_guru
0 / 0 / 0
Регистрация: 18.10.2011
Сообщений: 13
10.02.2013, 04:23  [ТС]     Один большой динамический массив вместо нескольких меньшего размера #5
Набросал простенькую прожку, чтобы убедиться на живом примере - все прекрасно работает.
Спасибо Вам большое!

Спасибо за совет - пока попробую реализовать работу через один большой динамический массив - если опять наткнусь на проблемы, которые не смогу решить, то буду изучать контейнеры - честно говоря мало про них знаю.

Добавлено через 16 минут
Попутно возник еще один вопрос.

Как снять ограничение в 2Gb для массива? Какая верхняя грань? Размер RAM?

Видимо вывод о том, что надо использовать динамический массив вместо статического - было ошибочным в том плане, что максимальный размер не увеличиться.
На данный момент могу задать массив, который будет содержать порядка нескольких десятков миллионов элементов. А как быть если этого мало?
Потому как если нужно держать в памяти порядка 30 параметров для каждого узла на двухмерной сетки, то получается, что максимально допустимый размер сетки будет порядка 800х800 - а это довольно скудно (в глобальном плане для моей задачи).

Заранее спасибо!
abit
 Аватар для abit
260 / 259 / 33
Регистрация: 03.02.2013
Сообщений: 709
10.02.2013, 04:28     Один большой динамический массив вместо нескольких меньшего размера #6
C++
1
Как снять ограничение в 2Gb для массива? Какая верхняя грань? Размер RAM?
ну там кроме рам есть другие факторы...
а как с этим работать... всё зависит от среды C++

сперва скажите что у вас возращает
cout << sizeof(size_t);

и поведайте о каких объёмах памяти мы говорим? если не знаете - скажите тип элементов массива (double я так понимаю?) и их количество
ken_guru
0 / 0 / 0
Регистрация: 18.10.2011
Сообщений: 13
10.02.2013, 04:35  [ТС]     Один большой динамический массив вместо нескольких меньшего размера #7
cout << sizeof(size_t); возвращает значение 4

Среда - MVS 2008 PE (на Win7 x64, размер RAM 8Gb)

Объемы памяти - Скорее всего порядка десятка Gb
использую не double, а long double - часто приходиться работать со значениями близкими к нулю и там важна большая точность - иначе решение задачи может начать расходиться.

А количество массивов - пока мне нужно 15 штук массивов, каждый их которых будет содержать данные с узлов сетки, сетка на данный момент 1000х100, но этого мало - нужен на порядок больше, где то 10000х1000
abit
 Аватар для abit
260 / 259 / 33
Регистрация: 03.02.2013
Сообщений: 709
10.02.2013, 04:57     Один большой динамический массив вместо нескольких меньшего размера #8
Цитата Сообщение от ken_guru Посмотреть сообщение
cout << sizeof(size_t); возвращает значение 4

Среда - MVS 2008 PE (на Win7 x64, размер RAM 8Gb)

Объемы памяти - Скорее всего порядка десятка Gb
использую не double, а long double - часто приходиться работать со значениями близкими к нулю и там важна большая точность - иначе решение задачи может начать расходиться.
так... ну в случае 64-битных систем вполне реально адресовать несколько 10-ков гигов, я конечно этим никогда не занимался)
собстна главное ограничение похоже у вас в size_t, т.е. при

a = new int (huge_mass);

это huge_mass у вас должно быть типа size_t (кстати если не так - исравьте) типа

C++
1
2
const size_t huge_mass = большое число;
a = new int (huge_mass);
однако, очевидно вам нужно ещё и иметь 64-битный компилятор C++ (MVS 2008 PE 64-битная?), чтобы работать с такой адресацией (у них свой предел для size_t)

второй вариант развития событий - это поглядеть на std::allocator, в одной из книжек я встречал как через него выделяли 16Гигов под что-то


но если не поможет, то я хз, никогда с такими объёмами не сталкивался в реальных задачах... вернее было один раз - но там тупо лог вёлся и надо было в минуту 2.5 гига снимать, но в файл... дождитесь завтрашнего дня - на форум придут бывалые мастера 64-Гигабитной адресации и помогут )



далее - не уловил связи со значениями близкими к нулю... или я чего-то не знаю ))) вы когда нибудь задумывались что означает слово "с плавающей запятой ", которое усердно приписывают во всех книжках к float/double?
в случае с double, что вы можете работать со значениями 10^(-308), т.е. 0.0..(тут 305 нулей)..01 куда вам ещё ближе к нулю? )
ken_guru
0 / 0 / 0
Регистрация: 18.10.2011
Сообщений: 13
10.02.2013, 05:16  [ТС]     Один большой динамический массив вместо нескольких меньшего размера #9
не совсем понял как использование числа типа size_t позволит задавать массив большего размера - пробовал так делать - все равно вылезает ошибка (общий размер массива не должен превышать 0x7fffffff байт)

Буду ждать завтра :-) Но все равно спасибо за предполагаемые варианты!

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

Простите - глупость говорю. Точнее написал не то, что хотел сказать - у меня не значения бывают близкими к нулю (точнее это тоже бывает - но не это главное), а изменения тех или иных значений. Например, энергии - а они должна сохраняться с хорошей точностью. К тому же в реальности фигурирует не энергия, а квадрат скорости...
Но возможно я чего-то не понял и мне достаточно использовать double. Но если я не ошибаюсь, то double - 8 байт, а long double - 10 байт -т.е. переход к double погоды не сделает.... или это неверно?
abit
 Аватар для abit
260 / 259 / 33
Регистрация: 03.02.2013
Сообщений: 709
10.02.2013, 05:28     Один большой динамический массив вместо нескольких меньшего размера #10
Цитата Сообщение от ken_guru Посмотреть сообщение
Простите - глупость говорю. Точнее написал не то, что хотел сказать - у меня не значения бывают близкими к нулю (точнее это тоже бывает - но не это главное), а изменения тех или иных значений. Например, энергии - а они должна сохраняться с хорошей точностью. К тому же в реальности фигурирует не энергия, а квадрат скорости...
Но возможно я чего-то не понял и мне достаточно использовать double. Но если я не ошибаюсь, то double - 8 байт, а long double - 10 байт -т.е. переход к double погоды не сделает.... или это неверно?
long double - 10 байт? вообще-то 16 в теории... это на 32-битных платформах 10, точнее в целях ускорения доступа (там адресация 32-битная предполагает кратность 4 байтам для большей скорости в памяти выделяется 12 байт)
поглядите на результат
cout<<sizeof(long double);
в вашей системе

если ответ 12, то вам нужен 64-битный компилятор, с этим у вас не получится адресовать больше 4Гигов
если ответ 16, то у вас всё ок...
кстати а позволяет он создать два массива по 0x7fffffff ? я так понимаю нет...

а квадрат скорости...
храните сами скорости, или изменения энергии... а перед подачей умножайте на нужные константы, возводите в квадрат и т.д. и у вас при double будет 15 значащих цифр в числе, что вполне сравнимо с квантом энергии при работе в Джоулях)))

четверная точность придумана малясь для другого насколько мне известно и причина больше в аппаратуре, чем в повседневной необходимости
ken_guru
0 / 0 / 0
Регистрация: 18.10.2011
Сообщений: 13
10.02.2013, 05:41  [ТС]     Один большой динамический массив вместо нескольких меньшего размера #11
У меня 32-битный компилятор. Когда начинал изучать C++ и пытаться писать прогу, то в одной из книжек прочитал, что 64-битный компилятор имеет ряд подводных камней и не рекомендуется для использования новичками.
Однако судя по той проблеме, которая возникла - надо будет переходить на x64

Странно, но у меня

sizeof(long double) возвращает значение 8
sizeof(double) - тоже возвращает значение 8...

Насчет энергии понял - спасибо, возьму на заметку и буду пытаться так реализовывать.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.02.2013, 16:53     Один большой динамический массив вместо нескольких меньшего размера
Еще ссылки по теме:

C++ Большой динамический массив
Дан динамический одномерный массив размера N, изменить размер массива до M C++
Скопировать один динамический массив в другой C++

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

Или воспользуйтесь поиском по форуму:
Lonkar
5 / 0 / 1
Регистрация: 10.02.2013
Сообщений: 7
10.02.2013, 16:53     Один большой динамический массив вместо нескольких меньшего размера #12
В MVS типы double и long double совпадают и имеют размер 8 байт.
Если нужно именно 10 байт, то придется использовать другой компилятор, например, gcc.

Про x64, к сожалению, ничего сказать не могу, но с удовольствием послушаю.
Разве FPU расширили с 80 бит до 128? Вроде нет, тогда я не очень понимаю, как long double может быть 16 байт.
Yandex
Объявления
10.02.2013, 16:53     Один большой динамический массив вместо нескольких меньшего размера
Ответ Создать тему
Опции темы

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