Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Проблемы с выделением памяти


Автор: DaJunior 8.6.2006, 11:33
People HELP!!!

Нужно память выделить 64000 байт(наверное все поняли зачем smile ), чет никак... smile
Пишу значит:

///////////////////////fragment//////////////////////////////
char *buf;
if(!(buf = new char[320*200])) cout<<"Нифига не получилось!";
///////////////////////fragment//////////////////////////////

Ну оно в принципе и понятно, почему не получилось: сегмент программы всего 64К.
Что делать, не знаю, не урезать же прогу до 1.5К(даже больше резать придется), да и что я в этот килобайт умещу...
Чего только делать не пробовал, и модель памяти менял... ничего не помогает...

Помогите, люди умные, уже 3-ий день голову ломаю... 

Автор: Romikgy 8.6.2006, 12:16
А че за система?
Имхо ограничение на эту цифру было под досом! 

Автор: DaJunior 8.6.2006, 12:33
Под ДОС'ом и пишу... так надо! =))) 

Автор: Romikgy 8.6.2006, 12:47
небось еще и на турбо си?!
зайди в настройки компилятора , где генерация кода и поставь модель памяти Huge, может поможет, я не проверял smile 

Автор: DaJunior 8.6.2006, 12:56
Я же писал, что модель памяти менял уже, них... не помогает... А Турбо Си - сила! Мне под дос нуно... вот! 

Автор: Romikgy 8.6.2006, 13:19
Цитата(DaJunior @  8.6.2006,  11:56 Найти цитируемый пост)
Я же писал, что модель памяти менял уже

гед?
Цитата(DaJunior @  8.6.2006,  11:56 Найти цитируемый пост)
А Турбо Си - сила!

Я бы не был так оптимистичен
дома поиграюсь , потом чет дельное отвечу, на работе нет доса,
кса а на два массива разбить нельзя? 

Автор: Replicator 8.6.2006, 13:21
Неужели С не может работать с динамической памятью? Сильно сомневаюсь. В TP это называлось "куча" и там можно было выделять память блоками не более 64К. Количество самих блоков ограничивалось только доступной ОС памятью.

Думаю, тут надо использовать что-то вроде getmem(), freemem(). 

Автор: regis 8.6.2006, 15:11
ИМХО, странная ситуация какая-то. В любой модели памяти с far-указателями по дефолту (даже не надо Huge, вполне достаточно Large) все должно прекрасно работать. Единственная возможная причина неудачи --- если память DOS (те самые 640K) вдруг кончилась. Мало вероятно, но... см. вывод команды mem перед запуском программы.
 

Автор: DaJunior 8.6.2006, 15:28
Ок, спасибо всем... Попробую работать через кучу, напрямую никак не получится, это я уже давно понял... пойду книжки умные читать... 

Автор: DaJunior 8.6.2006, 16:07
Нет чета ниче не получается... Я попробовал вот так:

///////////////////////fragment//////////////////////////////
char far *p = (char *) malloc(64000);
///////////////////////fragment//////////////////////////////

Хотя malloc - по сути - тот же new...

Но все та же фигня, не хочет он выделять столько памяти...
И по всей видимости выделяет её в near-куче, вместо far-кучи, но это еще пол беды, бог с ней, с near-кучей. Он пытается выделить память по тому же сегменту, что и сама прога висит... понятное дело, там не наберется 64000 байт, если сама прога будет в памяти занимать, пусть даже 2кб... Ведь сегмент программы(как я писал выше) ограничен 64кб(для тугих - 65536 байт)... Как мне заставить комп выделять память по другому сегменту, где уже свободно необходимое мне кол-во памяти??? Я уже всего Касаткина перерыл... Может проблема с компилятором??? хотя я пробовал в инсте - тоже глухо... Может кто сталкивался с этой проблемой??? 

Автор: likehood 8.6.2006, 17:15
может ты массив в стеке выделяешь? Попробуй сделать глобальный массив, при этом не забудь добавить перед ним far:
Код

far char buf[0xFFFF];


Кстати, если юзаешь Turbo C++ 3.0, то советую перейти на Borland C++ 3.1 - там глюков меньше. 

Автор: DaJunior 8.6.2006, 20:17
Сейчас попробовал так:

/////////////////////
char p[64000];
/////////////////////

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

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

P.S. кстати пишу на Borland C++ 3.1, а не на турбо, как некоторые подумали... 

Автор: DaJunior 9.6.2006, 06:26
Неужели никто не смог разобраться с этим вопросом??? Эй, мега программеры - где вы??? 

Автор: chaos 9.6.2006, 06:34
Цитата(DaJunior @ 8.6.2006,  20:17)
320*200 байт

до боли знакомый размер массива smile  не с видео памятью ли ты работаешь?
если нет, то у меня возникло две бредовых идеи
1) попользовать видео память для своих целей  smile 
2) перегрузить new delete (если конечно С++) и работать с диском

Добавлено @ 06:40 
а если с видео памятью работаешь то зачем тебе еще один массив? 

Автор: DaJunior 9.6.2006, 06:55
1) Да да, мне это нужно для работы с графикой! Кто с ней работал, наверняка знает о видео-страницах, но вот беда, в том режиме, в кот-ом пишу я - их просто нет(так что попользовать видео память - никак) smile((... поэтому надо съэмитировать их(вернее её)... иначе жуткие мерцания спрайтов - обеспечены smile((... 

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

Может кто-нить еще че подскажет??? 

Автор: chaos 9.6.2006, 07:13
Цитата(DaJunior @ 9.6.2006,  06:55)
но вот беда, в том режиме, в кот-ом пишу я - их просто нет

что-то я тебе не верю! smile что бы в таком режиме была всего одна страница.

если все же правдо, то придется переписывать на асм куски для "смены страниц". а вообще я бы не занимался мазахизмом а выбрал режим в которм есть пара страниц и ВСЕ!
Код

for(int nFrame = 0; true; nFrame++)
{
    setactivepage(nFrame & 1);
    setvisualpage((nFrame & 1) ^ 1);
    //.......
}
 

Автор: DaJunior 9.6.2006, 07:26
Я пишу в режиме 13h(VGA) - наверняка всем до боли знакомом. Это пожалуй самый удобный режим, но только вот проблема - всего одна видео страница...

Что касается стандартной библиотеки graphics.h - насколько помню корректно работать с видео страницами там можно только в одном режиме - причем довольно убогом(16 цветов + нестандартное разрешение экрана)... вот такие пироги...

В общем задача-то вроде не сложная, просто память выделить, а не получается... HELP. 

Автор: DaJunior 9.6.2006, 07:45
Да, кстати, забейте вы на эти альтернативные пути реш-ия проблемы. Мне конкретно нужно память выделить. Другие гр. режимы - это усложнение программы(не дай бог ещё программирование в защищенном режиме), алгоритма, как следствие - тормоз программы и возможно некорректная работа с различными видео картами(это я по поводу SVGA и X-MODE). Там проблем еще больше(в др. гр. режимах), а тут одна...

Блин, да видел я, люди выделяли столько памяти(давно это было), а сейчас сам не могу, что за... 

Автор: DaJunior 9.6.2006, 08:44
Сейчас еще один баг нашёл!!! Когда спрайты + прога занимают в памяти 64кб(т.е. полностью заполняют сегмент программы), прога отказывается дальше выделять память... т.е. много спрайтов сделать - никак... что за шляпа?!?!?!? Так что даже переход в др. видео режим - не есть решение проблемы... Я даже динамический спрайт создать не смогу(ну разве что из 5-ти кадров smile )... Я ограничен 64 кб!!!!!!! ПОМОГИТЕ КТО-НИБУДЬ!!!!!!! 

Автор: regis 9.6.2006, 12:42
Как я в общем и подозревал, malloc у тебя почему-то работает с near heap -- отсюда все проблемы.
Попробуй farmalloc / farfree.
 

Автор: likehood 9.6.2006, 13:16
DaJunior, а ты точно пробовал объявлять far - массив, т.е.
Код

far char buf[320*200];

Можно попробовать вместо far написать huge. Проверить не могу, BC++3.1 под рукой нет, но вроде должно работать. 

Автор: DaJunior 9.6.2006, 14:33
Вот, попробовал:

/////////////////////////////////////////////////////////////
void main()
{
clrscr();
char far *p;
p = (char *) farmalloc(64000);
printf("seg = %x off = %x adr = %x\n",FP_SEG(p),FP_OFF(p),p);
getch();
farfree(p);
}
/////////////////////////////////////////////////////////////

Ни в какую, после farmalloc указатель остается пустой... если выделять 60000 байт, то все ок. Думаю проблема в компиляторе. Попробуйте кто-нибудь(кому не лень) скомпилить у себя эту прогу(тока под дос есесноsmile) Сообщите о резалтах плз. 

Автор: bel_nikita 9.6.2006, 14:47
http://www.unix.org.ua/bcpp/r77_0.htm

Цитата
(не дай бог ещё программирование в защищенном режиме), алгоритма, как следствие - тормоз программы и возможно некорректная работа 

А в чем отличие защищенного режима от реального? smile 
 

Автор: likehood 9.6.2006, 15:14
DaJunior, объяви 
Код
char far buf[320*200L]; 

Вроде, должно работать. 

Автор: DaJunior 9.6.2006, 20:00
baronp - чет никак... 
bel_nikita - спасибо огромное, буду изучать! 

Автор: likehood 9.6.2006, 21:40
DaJunior, у меня все работает. Что хоть за ошибку он тебе выдает? 

Автор: MAKCim 10.6.2006, 09:31
Цитата

А в чем отличие защищенного режима от реального?

в защищенном режиме процессы защищены от взаимного влияния. В этом режиме процессором поддерживается 2 вида защиты: по привилегиям и по доступу к памяти 

Автор: DaJunior 10.6.2006, 14:30
baronp, 
прога выдает:

seg = 0 off=0 adr =0

следов-но память не выделена, вот! 

Автор: bsa 10.6.2006, 22:19
Подтверждаю, в BC 3.1 ни new char[320*200], ни malloc(320*200) в моделях памяти large и huge, не выделяют память.

DaJunior
Придется пользоваться allocmem'ом. smile
Хотя, на твоем месте, я бы поменял ОС. smile
 

Автор: likehood 11.6.2006, 11:23
DaJunior, еще раз говорю: массив надо объявлять статически. Динамически и вправду не выделяется. 

Автор: regis 13.6.2006, 13:22
Цитата(DaJunior @ 9.6.2006,  14:33)
Вот, попробовал:

/////////////////////////////////////////////////////////////
void main()
{
clrscr();
char far *p;
p = (char *) farmalloc(64000);
printf("seg = %x off = %x adr = %x\n",FP_SEG(p),FP_OFF(p),p);
getch();
farfree(p);
}
/////////////////////////////////////////////////////////////

Ни в какую, после farmalloc указатель остается пустой... если выделять 60000 байт, то все ок. Думаю проблема в компиляторе. Попробуйте кто-нибудь(кому не лень) скомпилить у себя эту прогу(тока под дос есесноsmile) Сообщите о резалтах плз.


Ну, разумеется, если используется farmalloc, то надо так:

Код

char far *p;
p = (char far *) farmalloc(64000);


Нет никакого смысла выделять far указатель и потом приводить его к near типу!!
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)