Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на C / C++


Информационный Канал Subscribe.Ru

РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / C/C++

Выпуск № 77
от 01.04.2005, 18:00

Администратор:Калашников О.А.
В номере:Вопросов: 1, Ответов: 8


Вопрос № 18852: Здравствуйте, уважаемые эксперты! Вопросы такие: 1) Мне нужно задать трехмерный массив, например, qwerty [256][256][256], все вроде нормально компилируется и линкуется, но при исполнении выскакивает ошибка про срыв стека. Опытным путем было в...

Вопрос № 18852
Здравствуйте, уважаемые эксперты!
Вопросы такие:
1) Мне нужно задать трехмерный массив, например, qwerty [256][256][256], все вроде нормально компилируется и линкуется, но при исполнении выскакивает ошибка про срыв стека. Опытным путем было выяснено, что появление ошибки связано с размерностью массива - т.е. некоторое критическое значение, после которого она появляется. А вопросы такие - а) это связано с количеством памяти или языком? б) как это обойти? а если мне нужны будут и массивы бОльших размеров? в) при чем тут стек???
2) Если информацию загонять файл, перемежая все это дело переводом строки и пробелами, то как при считывании этого файла эти пробелы игнорировать?
Т.е., например, если надо записать последовательность чисел в файл, они записываются через пробелы и в некоторых местах еще добавляется перевод строки. А потом нужно эти числа из файла считать в другой массив, как при это учитывать пробелы и переводы строки? По ASCII кодам 10h и 13h?? Или есть что-нибудь попроще?
3) Нужно при вставках кусков на ассемблере сохранять и восстанавливать стек?
Отправлен: 27.03.2005, 17:50
Вопрос задала: lupus campestris (статус: Специалист)
Всего ответов отправлено: 8

Отвечает: Malish
Здравствуйте, lupus campestris!
1) Попробуй создать массив динамически, через указатели, тогда ничего не будет переполняться.
2) Надо указывать в какой файл вносишь текстовый или двоичный, если в двоичный то никаких проблем - пробелы и переводы просто не нужны. А если в текстовый тогда надо сравнивать (а лучше открывать как записывал). НО НЕ ЗАБЫВАЙ ЧТО В ФАЙЛАХ СДЕЛАННЫЕ ВИНДОЙ ПЕРЕВОД НА НОВУЮ СТРОКУ !!!!
Открывай с таким сравнением (если текстовый) : значение>=48 && B<=57 - так только цифры (если надо только цифры) если другие знаки то вставляешь другие значения ASCII кода. И тогда не нужно отлавливать переводы строк и пробелов , только захватываешь только то что надо.
Ответ отправил: Malish (статус: 4-ый класс)
Отправлен: 27.03.2005, 19:12
Оценка за ответ: 5
Комментарий оценки:
Спасибо.
А у меня в текстовом файле под виндой просто переводит на другую строчку...
И насчет ASCII - я как-то привыкла думать, что цифры идут от 30h, понимаю, что это одно и тоже, но сначала цифра 48 меня напрягла. :)

Отвечает: dentist
Здравствуйте, lupus campestris!
1. используй malloc
2. а зачем тебе пробелы и переводы строки? открываеш файл для записи в бинарном режиме
file = fopen("name", "w+b") записываеш туда необходимые данные fwrite(&variable, sizeof(variabvle), 1, file).
а потом для чтения: file = fopen("name", "r+b"); fread(&variable, sizeof(variable), 1, file);
другое дело, если тебе нужен читабельный файл.
тогда файлы в текстовом режиме, и строками которые можно ещё и форматировать.
3. нет, если ты с ним корректно работаеш.
Ответ отправил: dentist (статус: 1-ый класс)
Отправлен: 27.03.2005, 20:31

Отвечает: __grey__
Здравствуйте, lupus campestris!
1)
Если размер массива известен, то поможет typedef + динамическое выделение памяти (см. Приложение 1).
2)
fscanf (см Приложение 2).

Приложение:

Ответ отправил: __grey__ (статус: 3-ий класс)
Отправлен: 27.03.2005, 20:50
Оценка за ответ: 5
Комментарий оценки:
Спасибо за очень подробный ответ!!!

Отвечает: _vt
Здравствуйте, lupus campestris!
1) Переменные, определяемые статически - т.е. непосредственно в теле программы - при компиляции размещаются в стеке. Для DOS по умолчанию размер стека равен 64Кб. Для других систем больше, но тоже размер ограничен. Ты пытаешься выделить 256*256*256=16Мб как минимум (это если элементы массива имеют размерность в байт). Слишком много :) Гораздо эффективнее создавать переменные динамически - т.е. в ходе работы программы - тогда им доступна вся оперативная память. Это делается с помощью процедур malloc/free (в языке C), или new/delete (в С++).
2) Не надо мудрить, есть стандартные методы записи/чтения файла, при которых будет записываться/считываться именно то, что нужно. Используй fprintf/fscanf (В С. В С++ сложнее, но там всегда можно использовать сишный способ :)).
3) Вообще это нежелательно, и зависит от компилятора. Например, для Borland C++ 5.6 сказано так:

In general, the rules of register use in an asm statement are the same as those of an external procedure or function. An asm statement must preserve the EDI, ESI, ESP, EBP, and EBX registers, but can freely modify the EAX, ECX, and EDX registers. On entry to an asm statement, EBP points to the current stack frame and ESP points to the top of the stack. Except for ESP and EBP, an asm statement can assume nothing about register contents on entry to the statement.
--

* In Gates we trust! :)

Ответ отправил: _vt (статус: Академик)
Отправлен: 27.03.2005, 21:52
Оценка за ответ: 5
Комментарий оценки:
ОК, спасибо!!!

Отвечает: Bob Johnson
Здравствуйте, lupus campestris!
1. Ты скорее всего создаешь такой массив как локальную переменную? они помещаются в стек, которого действительно может не хватить, поэтому лучше выделяй себе память с пом. new.
2. есть функции sscanf и fscanf. они все это позволяют делать.
3. зависит от компилятора. в свое время в watcom С++ можно было с пом. pragma указать, какие регистры использует твой код на асме. в общем случае, лучше сохранять и восстанавливать.

* EMan2.0: ---===*** Debug mode ***===---

Ответ отправил: Bob Johnson (статус: Академик)
Отправлен: 28.03.2005, 00:05
Оценка за ответ: 5
Комментарий оценки:
Спасибо! Немного стало яснее.

Отвечает: vitya
Здравствуйте, lupus campestris!
1. СОздавай данные в куче
2. потом пропускать эти пробелы и переводы строки,
Ответ отправил: vitya (статус: Профессор)
Отправлен: 28.03.2005, 09:49

Отвечает: DSota
Здравствуйте, lupus campestris!
3. При вставке указатель стека SP - можно менять как хочется (в определенных пределах конечно)...
Он сохраняется в регистре BP... а вот изменение самого регистра BP ведет к сбоям...
Ответ отправил: DSota (статус: Студент)
Отправлен: 28.03.2005, 12:31

Отвечает: Voituk Alexander
Здравствуйте, lupus campestris!
1. Если ты пишешь под DOS то все понятно. Ты памяти больще чем 64К не выделишь, особенно в стеке. А стек здесь при том, что если это не глобальная переменная, то она железно выделяется в стеке. Если нужны большие массивы и прога под DOS - пиши в защищенном режиме. Например, компилятор Watcom C++ позволяет это легко. Там свободно создаются мегабайтные массивы.
2. Я написал прогу на Borland C++ 3.1 см. приложение. Читае float из текстового файла, и пофиг ей пробелы и переводы строки.
3. При этом ничего не нужно сохранять, если ты явно сам для каких-то целей этого делать не будешь.

Приложение:

Ответ отправил: Voituk Alexander (статус: 6-ой класс)
Отправлен: 28.03.2005, 12:47


Отправить вопрос экспертам этой рассылки

Приложение (если необходимо):

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2005, RusFAQ.ru, Россия, Москва. Все права защищены.
Идея, дизайн, программирование, авторское право: Калашников О.А.


http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.cplus
Отписаться

В избранное