Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.05.2011, 21:09   #1
Вадим Мошев

Старожил
 
Аватар для Вадим Мошев
 
Регистрация: 12.11.2010
Сообщений: 8,568
По умолчанию Возникает ошибка при выделении памяти для элемента типа TStringList динамического массива записей.

Здравствуйте!

У меня возникает проблема, с которой я не могу разобраться самостоятельно.

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

Код:
type
  TQuestion = record  

                    QuestionText: TStringList; // ВОТ ОН!!!
                    StringsAmount: byte; // Число строк в тексте вопроса
                    Way: string[8]; // способ ответа на вопрос
                    AnswerVariant: array [1..6] of string; // варианты ответа на вопрос
                    Bound: 1..6; // Порог
                    EditAnswer: string; // Правильный ответ на вопрос, вводимый с клавиатуры
                    GivenAnswer: string; // Ответ введённый пользователем
                    CaseSensitive: boolean; // флаг регистрочувствительности
                    Answered: boolean;   // признак того, что на вопрос дан ответ
                    Right: boolean; // Признак того, что на вопрос дан ВЕРНЫЙ ответ
                 end;
Также у меня объявлена переменная (глобальная), которая является динамическим массивом записей TQuestion:

Код:
Question: Array of TQuestion; // Динамический массив
Разумеется, прежде, чем работать с динамическим массивом, надо установить для него длину посредством процедуры SetLength. Это происходит у меня так:

Код:
// Создать массив для нужного числа вопросов
        SetLength(Question, beforeTest.amountToTest);
В данном случае, у меня второй параметр этой процедуры заведомо не может быть меньше единицы, то есть минимум, чему он может быть равен – это 1.
Таким образом, проблем здесь не возникает.

Проблемы же начинаются далее, когда, как было написано в названии темы, пытаюсь выделить для поля QuestionText (см. выше) память.
Поскольку Это поле принадлежит записи Question, вернее, элементам этого массива, то есть записи, то проблемная операция выглядит следующим образом:

Код:
Question[t].QuestionText.Create;
Вот в этой строке ошибка.
Здесь написано: для t-го элемента массива записей Question, его поля QuestionText (типа TStringList) выделить память.

Возникает ошибка:

Цитата:
---------------------------
Debugger Exception Notification
---------------------------
Project VIRTUAL_EXAMENATOR.exe raised exception class EAccessViolation with message 'Нарушение доступа по адресу 00403F21 в модуле 'VIRTUAL_EXAMENATOR.exe'. Чтение по адресу 00000000'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
Часть этого кода выглядит следующим образом:

Код:
for j:=1 to LastNumber do
                           begin
                             if j in QuestionsNumber
                                                then // Попался вопрос с нужным номером
                                                  begin
                                                    inc(t); // t - порядковый номер вопр в записи
                                                    // Читаем
                                                        ReadLn(F); // номер вопроса в файле. Попускаем
                                                        ReadLn(F, Question[t].StringsAmount); {кол-во
                                                                                                строк
                                                                                              в тексте
                                                                                              вопроса}

                                                        // Выделить память для текста вопроса
                                                            Question[t].QuestionText.Create; // ЗДЕСЬ ОШИБКА!

                                                        // Читаем текст вопроса построчно
                                                            for k:=0 to Question[t].StringsAmount-1 do
                                                                                         begin
                                                                                           ReadLn(F, sbuf);
                                                                                           Question[t].QuestionText.Add(sbuf)
                                                                                         end;
//…………………………...……………………………………….
Переменная t до самого первого её инкремента равна (-1), а после него равна 0, то есть нумерация в динамическом массиве у меня идёт с нуля, как должно быть.

Подскажите мне, в чёму меня дело, пожалуйста.
Заранее благодарю!
Вадим Мошев вне форума Ответить с цитированием
Старый 27.05.2011, 21:14   #2
Valio
Сливочное масло
Участник клуба
 
Аватар для Valio
 
Регистрация: 01.01.2011
Сообщений: 1,149
По умолчанию

Лень было всё читать но могу сказать:

Код:
Question[t].QuestionText := TStringList.Create;
Вот так создают его.
Сливочное масло Valio - компиляция как по маслу
Valio вне форума Ответить с цитированием
Старый 27.05.2011, 23:43   #3
Вадим Мошев

Старожил
 
Аватар для Вадим Мошев
 
Регистрация: 12.11.2010
Сообщений: 8,568
По умолчанию

Valio Спасибо большое тебе.

Вот какой я забывчивый или невнимательный. Я же в прошлом модуле работал с типом СтрингЛист, и там я делал всё правильно, а тут что-то забыл... может устал я просто, мозги забиты.
Хотя в прошлом модуле вместо динамических массивов были однонаправленные списки, но это сути не меняет.
А может, это из-за того, что я с этим типом недавно знаком?...

Забаните меня за невнимательность
Вадим Мошев вне форума Ответить с цитированием
Старый 28.05.2011, 02:56   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
А может, это из-за того, что я с этим типом недавно знаком?...
обьект любого класса создается по принципу
<переменная>:=<имя класса>.<имя конструктора>(<параметры>);
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 28.05.2011, 08:01   #5
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

а я ещё наблюдаю странную штуку - массив динамический, нумерация, естественно, с 0, а inc(t) происходит до обращения к t-ому элементу массива questions, т.е. может сложится обращение questions[1] хотя длина массива может быть тоже 1, и, соответственно, индекс первого элемента массива будет не 1 а 0 !

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

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

и, да, первый совет - мешанина из рекордов, массивов, классов и переменных достаточно неприглядная (( взять уж хотя бы переменную stringsamount при живом stringlist'e , вот не уследили Вы в коде , и количество строк в самом стринглисте может быть изменено, а переменная stringsamount нет, и что тогда ? если уж делаете классы, то делайте классы.. Tcollection и Tlist Вам в помощь

Последний раз редактировалось phomm; 28.05.2011 в 08:09.
phomm вне форума Ответить с цитированием
Старый 28.05.2011, 10:48   #6
Вадим Мошев

Старожил
 
Аватар для Вадим Мошев
 
Регистрация: 12.11.2010
Сообщений: 8,568
По умолчанию

phomm

Цитата:
а я ещё наблюдаю странную штуку - массив динамический, нумерация, естественно, с 0, а inc(t) происходит до обращения к t-ому элементу массива questions, т.е. может сложится обращение questions[1] хотя длина массива может быть тоже 1, и, соответственно, индекс первого элемента массива будет не 1 а 0 !
У меня же было написано, что до самого первого обращения к инкременту, переменная t устанавливается в (-1), то есть, t:=-1;
Таким образом, нумерация динамического массива будет всегда с нуля... если я вас праивльно понимаю...

Цитата:
коли желаем, могу поделиться мыслями по поводу написания экзаменатора, у самого сурьезноспроектированный оный...
Спасибо большое, я приму к сведению, но, может, не в ближайшее время... Контакты, вроде, у вас есть, если что, обращусь...
Вадим Мошев вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка доступа при выделении памяти в чужом процессе Neoteric Общие вопросы Delphi 21 06.12.2010 16:50
Создание класса с полем типа TStringList. Ошибка при его заполнении Son Общие вопросы Delphi 8 13.04.2010 21:38
Ошибка при очистке динамического массива. S_Yevgeniy Помощь студентам 4 24.12.2009 18:45
почему может возникать ошибка access violation...: write of address при создании динамического массива sleevman Помощь студентам 16 03.11.2009 20:49
Удаление элемента динамического массива Dogmat Помощь студентам 6 13.07.2008 14:33