Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Dev-Cpp. Начало.  (Прочитано 23846 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Etien
Интересующийся

ru
Offline Offline
Пол: Мужской

« : 08-01-2010 16:25 » 

   Дорогие Коллеги!
 
  У меня как-то вышла нужда "засосать" под программу целый (int) массив из примерно 1.5 миллионов элементов. Это картинка. И сделать это я пытался с
помощью доступного к скачиванию через I-net "Dev-Cpp 4.9.9.2".

   Увы, номер не прошел. Еще cрабатывает примерно  int array[500000], а дальше диагностирует сбой в процессе выполнения. Трансляция проходит!

   Большая просьба к истинным Гуру подсказать финиш ли это, или? Если "или" - то что нужно подстроить, чтобы 1.5 миллиона элементов массива не ставили программу в столь интересную позу.

   Общался до того с самыми разными трансляторами С\С++, но конкретно Dev-Cpp вижу впервые.

   С благодарностью - ваш Этьен.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #1 : 08-01-2010 16:35 » 

проблемы могут быть минимум:

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

в любом случае 1.5E6 это не ахти какой объём данных и проблем быть не должно
нужен полный код программы и сообщение об ошибке
Записан

Странно всё это....
Etien
Интересующийся

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 08-01-2010 17:22 » 

   Собственно программы еще нет.

#include <stdio.h>
#include <stdlib.h>
main( )
{ int array[500000];
  system(" Pause! "); }

   Засосал из I-net'a  "Dev-Cpp", надеялся быстро проверить годится  ли. Трансляция и сборка проходит успешно. При запуске консольного приложения *.exe и размерности массива int array[1500000] выдается сообщение системы :

...exe has encountered a problem and needs to close. We are sorry for the inconvenience.

   Более детальный просмотр выдает какие-то адреса где произошел сбой. Они мне ничего не говорят. Окошко консольного приложения зависает не дойдя до " Pause! ".

   При размерности массива int array[500000] все проходит успешно и массивом можно пользоваться. Проверил.

   Нигде явно ни стеком, ни кучей, ни динамическими определениями массивов не пользуюсь.

   Всегда Ваш - Этьен.
Записан
kogemrka
Гость
« Ответ #3 : 08-01-2010 17:24 » 

Попробуй вместо int array[500000] объявить int *array (указатель на int)

А затем сделать
array = malloc(500000 * sizof(int));

А в конце программы добавить free(array);

Если проблема была в том, что массив слишком велик для размещения в стеке, всё должно заработать
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 08-01-2010 17:26 » 

Etien, не читаешь, что тебе пишут.

Код:
int* p=new [1500000];



if(p)delete [] p;
p=0;
Записан

Etien
Интересующийся

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 08-01-2010 17:35 » 

    Пардон, месье! У меня в честь праздника Интернет работает через пень-колоду. Сейчас буду пробовать. Это на другом компе варится.
    Ваш - Этьен.

Merci bien! Похоже так оно работает. А без динамики никак? Всегда ваш - Этьен.
« Последнее редактирование: 12-01-2010 09:22 от Sel » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 08-01-2010 17:50 » 

Etien, нет, никак, наш Этьен Улыбаюсь
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #7 : 12-01-2010 04:32 » 

Нигде явно ни стеком, ни кучей, ни динамическими определениями массивов не пользуюсь.

чему вас только учат? Улыбаюсь
Код:
.........
void foo(int i) // параметры в стеке
{
.......
int c; // локальные переменные в стеке
int d[500]; // локальные переменные в стеке
...........
int * e = new int[50000]; // e в стеке, а *е в куче
.......
}

стек не бесконечный, поаккуратней с ним.
Записан

Странно всё это....
Etien
Интересующийся

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 16-01-2010 20:43 » 

  Да пока никто не жаловался на учебу. Но в распределении памяти детально конечно не разбирался.

  Рекомендацию "... поаккуратнее со стеком..." постараюсь учесть. Ну и тогда уже заодно подскажите можно ли заказать и\или изменить емкость конкретного стека. Все же массив в полтора миллиона элементов не должен вызывать столь аллергическую реакцию системы. К тому-же реально мне нужен несколькомерный массив с соответствующим числом элементов, а добираться туда с помощью указателей несколько безрадостно. Ну нет тут ничего столь особенного, чтобы тащить в программу динамическое распределение памяти.

 С благодарностью - Ваш Этьен.

Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 17-01-2010 04:30 » 

Etien, брось загадками говорить, задачу в студию Улыбаюсь
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 17-01-2010 08:41 » 

Цитата: Etien
Ну нет тут ничего столь особенного, чтобы тащить в программу динамическое распределение памяти.
А нет ничего особенного в динамическом распределении памяти, чтобы его не тащить в программу Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 17-01-2010 10:20 » 

Все же массив в полтора миллиона элементов не должен вызывать столь аллергическую реакцию системы.

Etien, вот бы тебе на Symbian попрограммировать Улыбаюсь Там вообще на стеке можно создавать только о-очень маленькие объекты, потому что сам стек - несколько килобайт. Всё-таки, есть огромная разница между Stack Overflow и нехваткой памяти. И неважно, можно ли управлять размерами стека (часто это возможно).

Переполнение стека означает, что программа вообще не может дальше выполняться, потому что стек - критический ресурс, без него никакой вызов функции невозможен, не говоря уже о локальных переменных. А если в куче не хватит памяти- ты эту ситуацию ещё можешь обработать, потому что она не затрагивает стек вызовов, и программа может выполняться более-менее нормально в том смысле, что будет продолжать нормально оперировать со стеком.
Записан
Etien
Интересующийся

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 17-01-2010 11:49 » 

Цитата
А нет ничего особенного в динамическом распределении памяти, чтобы его не тащить в программу Улыбаюсь
 Ну "С" стандарт ничего не знает о динамических массивах. Это дополнение, расширение, надстройка - как угодно. Мапссив, в том числе многомерный есть стандарт. И в этом стандарте ничего не сказано о критическом числе [500000]. Мне же просто удобнее оперировать именно с массивом, а не с указателями, если конечно это принципиально возможно.
  С уважением - ваш Этьен.
« Последнее редактирование: 17-01-2010 15:36 от Sel » Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 17-01-2010 11:51 » 

Управление автоматическим расширением стека на x86 лимитируется, в основном, тем, что стек нельзя перемещать в адресном пространстве процесса и потому он зафиксирован в положении. Система выделяет в виртуальном пространстве процесса блок, куда по мере роста стека добавляет страницы. Если этот блок будет переполнен, то придется его расширять его вниз, но там уже могут быть другие данные и потому этого не позволяется. Более того, существуют лимиты, административно ограничивающие процесс в ресурсах.

Код:
$ ulimit -s
10240

Вот - лимит в 10 Мб.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 17-01-2010 11:53 » 

Etien, как тебе странно бы не показалось, но стандарт знает. Есть понятие стандартной библиотеки.

Для Си - функции malloc() и free().
Для C++ - операторы new  и delete.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Etien
Интересующийся

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 17-01-2010 12:22 » 

 Пардон, Месье. Не готов согласиться.

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

 Оперируя с открытием массива
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 17-01-2010 12:44 » 

Мапссив, в том числе многомерный есть стандарт. И в этом стандарте ничего не сказано о критическом числе [500000]. Мне же просто удобнее оперировать именно с массивом, а не с указателями, если конечно это принципиально возможно.
А ещё, массив, в том числе и многомерный, требует, чтобы размерности были константами (по-моему, только в самое последнее время появилась возможность объявлять массивы с внешними переменными в качестве размерностей, но не уверен, включили ли это уже в стандарт, и поддерживается ли компиляторами). Другой способ создания массива - объявление без указания размерностей, но сразу с инициализацией. Таким образом, размерность всё равно остаётся константной, просто заданной неявно в инициализирующем выражении.

Поэтому статический массив - это очень статичная сущность. Его размеры должны быть определены на этапе компиляции - а значит, чётко мотивированы. Потому что нет возможности превысить это ограничение, увеличить массив во время выполнения, а любой "запас на всякий случай" рано или поздно может оказаться недостаточным. И, кроме всего, отнимает драгоценное место на стеке.

Таким образом, статический массив предназначен скорее для ситуаций, когда программист точно знает об ограничениях в объёме обрабатываемых данных (так, например, дискретное косинусное преобразование выполняется в конкретном кодеке блоками 4x4 - и никак иначе). А для всех безразмерных объёмов данных (сегодня килобайт - завтра мегабайт - послезавтра 100К) используется место на куче - место для больших объёмов данных. Даже если эти объёмы маленькие - для того память и динамическая, чтобы размещать там динамические структуры.

Поэтому твоё требование "хочу 500К массив на стеке" выглядит пока как взятое с потолка. Ведь где 500К - там и 1000, и гигабайт, а стек не резиновый.
« Последнее редактирование: 17-01-2010 12:46 от Вад » Записан
Etien
Интересующийся

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 17-01-2010 12:45 » 

  Дорогой Месье RXL.

 Eсли не трудно, чуть подробнее о административных возможностях. Где, когда и как я могу задать указанному процессу лимиты на емкость памяти под стек? Под лок. данные?

  И большая просьба не поскупиться на пару объяснительных фраз. Такие вещи пока делать не доводилось, а видимо прийдется.

  Всегда ваш - Этьен.

Записан
Etien
Интересующийся

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 17-01-2010 12:55 » 

   Дорогой Месье Вад!

   Пожелание иметь именно массив и именно такой размерности не упало с потолка. Я здесь попытался сформулировать решаемую задачку, но сорвало комп и ввод исчез, а перебивать еще раз меня ломало.

   Обрабатывается картинка с черно-белой TV камеры. Ее матрица имеет фиксированный объем и два измерения. Суммарно - около 1 500 000 элементов. Этот объем неизменен для всех кадров с камеры. Индекс такого массива есть просто адрес пикселя в соотв. координате, что безусловно много удобнее, чем пересичитывать где-то отдельно указатели. В процессе работы емкость этого массива не меняется. Больше никаких капризов с моей стороны.

  С уважением - Этьен.
« Последнее редактирование: 17-01-2010 15:36 от Sel » Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #19 : 17-01-2010 13:44 » 

Etien, все это вода и не более того! Большие массивы в стеке хранить нельзя и обсуждать тут нечего. Хочется геморроя - пожалуйста, хочется стабильности - используй кучу. Только мозги нам загружать этим не надо.

Код:
#define CAM_WIDTH 1024
#define CAM_HEIGHT 768

struct pixel
{
  char r;
  char g;
  char b;
  char __align;
};

struct pixel *buffer = (struct pixel *)malloc(sizeof(struct pixel) * CAM_WIDTH * CAM_HEIGHT);
int x = 100;
int y = 200;
struct pixel *p = buffer[y * CAM_WIDTH + x];

Что здесь сложного?



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

По лимитам - см. документацию на свою ОС.
Для Unix-подобных систем все просто: команда ulimit расскажет о лимитах и позволит динамически их сокращать (расширять может только root).
Для компиляции под MinGW, видимо, придется обратиться к MSDN.

« Последнее редактирование: 17-01-2010 13:51 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Etien
Интересующийся

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 17-01-2010 14:18 » 

  Да нет. Собственно свою частную проблему я преодолел еще с совершенно справедливым и своевременным первым из ответов. Хотя далеко не самым элегантным способом.

  Все остальное - желание разобраться в проблеме. Видимо наиболее правильный совет здесь - изучать матчасть (документацию).

  Всем ответившим - спасибо! Зачтется.

  Уважаемому RXL персональная благодарность. Действительно, некоторые мозги загружать не надо. Тоже учту.

"... Только мозги нам загружать этим не надо..."

  С уважением - ваш Этьен.

Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 17-01-2010 14:24 » 

Etien, Рома имеет в виду, что если ты хочешь побеседовать на тему "всё-таки стек - резиновый", то не утруждай себя и других Улыбаюсь
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 17-01-2010 14:32 » 

Чтобы не загружать мозги, есть много более удобных абстракций, чем статический массив. В случае C++ - для этого и есть стандартные и самописные шаблонные контейнеры, чтобы хранить что угодно нужного размера с удобным доступом.

Статический же массив - имхо, классический пример дырявой абстракции. И тут я отчасти согласен с Etien - действительно, на первый взгляд, вполне логично было бы использовать статический двумерный массив - ведь он же дозволяется языком как структура. Но реализация статических массивов (как объектов на стеке) вылезает из-под абстракции и накладывает ограничения на использование таких массивов. Хотя их использование выглядит проще и нагляднее. Языки высокого уровня обходят это, просто не позволяя создавать массив на стеке, и позволяя создавать многомерные массивы. Но C/C++ - это не язык высокого уровня. А потому - нужно учить матчасть и со смирением принимать ограничения, налагаемые реализацией Улыбаюсь

зы. Etien, то, что камера сегодня имеет такое разрешение - не означает, что завтра к программе не подключат камеру бОльшего разрешения. А писать программу/драйвер под каждую конкретную камеру - это как-то...
« Последнее редактирование: 17-01-2010 14:35 от Вад » Записан
Etien
Интересующийся

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 17-01-2010 15:50 » new

  Еще раз - всем ответившим - благодарность. Конкретная частность - решена. Какие либо обобщения буду делать по мере ... Возникнет конкретный вопрос - не постесняюсь спросить. Пытаться обсудить здесь абстрактно-теоретический скорее вопрос здесь явно не к месту. "Учение Ленина истинно потому что оно верно!" Работает что - ну и ладненько. Всем удач! Свалил программировать. Ваш Этьен.

 
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines