![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Profi80 |
|
||||||
|
Unregistered |
Уважаемые коллеги, прошу вас помочь с разбором кода open source трекера (программы для написания музыки). Главным образом, мои вопросы касаются работы со структурами. Я уже несколько дней пытаюсь понять алгоритм работы одного участка кода, но пока безуспешно. Надеюсь среди вас найдутся спецы, для которых решение этой задачки не составит большого труда. Вот код:
Файл a.cpp содержит инициализацию структуры extern sound_struct xm; для глобального использования (структура содержит информацию о музыкальном треке). объявление структур sound_struct и module в файле b.h:
Процесс загрузки трекерного модуля начинается с файла c.cpp, который содержит следующую функцию: load_module( name, &xm ); //загружаем музыкальный модуль определение функции в файле d.cpp :
переходим в функцию xm_load( f, xm ), её определение в файле e.cpp:
*пояснение: fread(sptr+4,332,1,f) - функция перемещает 322 байта из файла с дескриптором f в *sprt ВНИМАНИЕ! ВОПРОСЫ: 1. Можно ли таким образом: char *sptr = (char*)song; fread(sptr,332,1,f); //load header проинициализировать структуру module* song; в структуре sound_struct xm; (скопировать данные из файла по адрусу указателя). Дебаггер говорит, что нельзя :-), тогда зачем это здесь? 2. Почему не удаётся записать данные в id_text[] таким образом: song->id_text[0] = 'E'; song->id_text[1] = 'x'; song->id_text[2] = 't'; song->id_text[3] = 'e'; ? 3. Обязательно ли инициализировать структуру, чтобы давать указатель на неё? Структура sound_struct содержит указатель на структуру module* song; При обращении к её элементам (song->id_text[0] = 'E';) куда записываются данные- в sound_struct или куда-то в другое место? Заранее спасибо! |
||||||
|
|||||||
| LPBOY |
|
||||||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 228 Регистрация: 12.7.2005 Репутация: 20 Всего: 20 |
Я не спец, но попробую высказать свое мнение... (оно может быть и субъективным, конечно).
Думаю можно. Но инициализация происходит "насильственным" способом, через опасные приведения типов и прямую запись по адресу памяти. Хотя для С обычный прием - полагаться на внутренне представление данных, (а в С++ это скорее хак), ведь С - язык системного программирования. Неудивительно, что это не нравится деббагеру (компилятор наверно С++, а не С?), хотя фактически ошибки нет, ИМХО.
Почему не удается? Что говорит компилятор\деббагер?
В принципе достаточно чтобы указатель указывал на существующую структуру пусть и не инициализированную. Но опять-таки деббагер С++ может ругаться.
Фактически они записываются в структуру module, которая является полем структуры sound_struct. P.S. Интересно узнать название твоего компилятора. Это сообщение отредактировал(а) LPBOY - 6.8.2005, 12:43 --------------------
Каждый человек по-своему прав, а по-моему нет... |
||||||||||
|
|||||||||||
| Profi80 |
|
|||
|
Unregistered |
To LPBOY: Спасибо, что откликнулся и попытался помочь. Я пишу в Codewarrior, компилятор C++.
На самом деле причина ошибок была вот в чём - т.к. в sound_struct был задан указатель module* song; и нигде не была инициализирована переменная типа module, указатель естественно указывал на ноль! И потому как это структура, а не char или int, данные уходили в никуда Решение заключается в том, чтобы указатель получил какой-то реальный адрес, а именно вот так: module* song[1]; после этого можно обращаться к полям структуры module в структуре sound_struct. Как всегда, разобраться помог дебаггер + крепкий кофе на ночь Но, так и не понял, почему автор исходников написал именно так, как было? И как оно всё работало? Видимо, на С такое допускается... (кстати, код написан по уверениям автора под gcc, но судя по манере исполнения это больше похоже на C, чем на C++) |
|||
|
||||
| LPBOY |
|
||||||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 228 Регистрация: 12.7.2005 Репутация: 20 Всего: 20 |
Ты меня не понял.
Подожди... Если указатель указывал на ноль, это не значит, что "нигде не была инициализирована переменная типа module", а значит что ее и вовсе нету. Если же она есть (т.е. где-то была создана и ее адрес присвоен указателю song), но просто не инициализирована, то тут все в порядке!
Опять не согласен. В книжках по системному программированию я очень часто встречал такой приём. Так делают, чтобы не заморачиваться с присваиванием каждому полю структуры, а заполнить ее одним махом, заранее подготовленной побайтовой копией инициализированной структуры из файла. Данные не уходили "вникуда", т.к. адрес-то не менялся, происходило лишь преобразование типа указателя (char*)song в char*, т.е. структура рассматривалась как последовательность байтов. Тут происходит следующее: module *song = (module*) xm->song; char *sptr = (char*)song;//Структура module трактуется как последовательность однобайтных символов. fread(sptr+4,332,1,f); //Затем она заполняется (инициализируется) "одним махом" из файла. Первые 4 байта не инициализируются как видишь, - они инициализируются "обычным" способом:
Cтруктура module может быть не инициализирована, но ОНА ОБЯЗАТЕЛЬНО ДОЛЖНА БЫТЬ СОЗДАНА, И ЕЕ АДРЕС ДОЛЖЕН БЫТЬ ПРИСВОЕН УКАЗАТЕЛЮ song. Т.е. где-то должен быть такой код:
Если он есть, то ИМХО все OK. (Попробуй поискать).
Ты просто создал массив из одного элемента типа module*. Возможно ты этим просто отбил деббагеру охоту ругаться. На внутренне уровне ничего не изменилось. Но он не получит "реальный адрес" структуры module сам по себе, если ее нету! - Это же просто указатель. Обязательно должно быть где-то: module m; xm.song=&m; В общем ИМХО тут все OK... P.S. open source говоришь? А можно ссылку на эти исходники? ;) Это сообщение отредактировал(а) LPBOY - 7.8.2005, 03:03 --------------------
Каждый человек по-своему прав, а по-моему нет... |
||||||||||
|
|||||||||||
| Profi80 |
|
|||
|
Unregistered |
Вот в том то и дело, что структура module нигде не инициализирована! Всё было бы понятно, если бы где-нибудь была инициализация. Но я её нигде не нашёл - поэтому и возник этот вопрос! А на самом деле, когда создал массив из одного элемента module, появилась другая проблема - память в структуре sound_struct выделилась в размере 4 байта (как раз под адрес), и просле чтения из файла данные после первых четырёх байт записались в соседнюю структуру channels. Так что решение не помогло...
Всё-таки я не понимаю как это должно работать... Вот, можешь посмотреть сам исходники: Исходники |
|||
|
||||
| Profi80 |
|
|||
|
Unregistered |
Извиняюсь, опечатка была. Я хотел сказать, что структура нигде не создана. Т.е. нигде нет кода типа module m; xm.song=&m;
Устал сегодня, опять ковырял код... Надо же постараться так написать, что потом ничего не разберешь.. |
|||
|
||||
| Romikgy |
|
||||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 8 Всего: 146 |
Я не полностью разбирался, но там где -то должен быть вызов функции sound_stream_init(), в ней есть еще одна функция
И вот в реализации этой функции:
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
||||
|
|||||
| LPBOY |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 228 Регистрация: 12.7.2005 Репутация: 20 Всего: 20 |
2Romikgy, точно
Но главное, что она выделяется 2Profi80 Скачал исходник, все скомпилировалось и запустилось. Единственное что я изменил - раскомментировал дефайны
а остальные закомментировал (в core.h). - Это было написано в документации (для win32). Компилировал на MSVC 7.1 (там и проект для VC6 лежал, поэтому проблем не возникло). Думаю, тут дело не в ошибках в программе, а в переносе на другой компилятор... Это сообщение отредактировал(а) LPBOY - 8.8.2005, 09:57 --------------------
Каждый человек по-своему прав, а по-моему нет... |
|||
|
||||
| Profi80 |
|
|||
|
Unregistered |
А я не под Win32 компилирую, а под Palm OS 5.4.
В Codewarrior 9 не компилируется (если без Armlet-ов), линкер ругается... Наверное действительно дело в компиляторе... To Romikgy я наверное не в той последовательности код смотрел, полагал что sound_stream_init() вызывается позже, а видимо наоборот - спасибо что подсказал! |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |