MadEd
http://facebook.com/fb.stas
Гродненец
Репутация: +11/-0
Offline
Пол:
Сообщений: 266
Permanently drunk...
|
|
« : 06 Июнь 2005, 12:42:14 » |
|
Всем привет, короче такая история. Есть двоичный файл, в который с помощью out.write. где out - это ofstream, записан вектор моих собственных объектов. Размерность объекта предположим 52 байта (одно int поле и 3 string), вектор из трёх элементов(пока), имеем out.write((char*), &myVector, sizeof(myObject) * myVector.size()); Записали - проверили, файл есть длинной аккурат 156 байт. Теперь его надо прчитать и вот тут начинается гемморой:
myVector пока пуст, пишу in.read((char *) &myVector, 156); cout<<myVector.size(); myObject = myVector[0]; И начинается попа - валится access violation, плюс какой то debug error damage in heap и прочие яйца, иногда прга успевает вывести размер вектора, но всегда конец один итот же "программа выполнила недопустимую операцию" в Win98 и чё-то там такое же в ХР
Вопрос - что я делаю не так? Почему когда я записываю в файл двоичные данные примитивных типов (double например) - такого при их считывании не происходит. Путём сотни перезапусков установлено, что проблема всегда с stl-ными контейнерами (с обычными массивами всё намана) + с моими типами данных, т.е myClass qwe[5] - предположим, то же не работает
Памажице людзи добрые чым можаце, бо я ужо за*б*уся!!!
|
|
|
Записан
|
|
|
|
Мандарин
|
Может это и флейм , но - занимайся работой Ж))))
|
|
« Последнее редактирование: 06 Июнь 2005, 15:27:38 от mandarin »
|
Записан
|
|
|
|
Archi
|
out.write((char*), &myVector, sizeof(myObject) * myVector.size()); Записали - проверили, файл есть длинной аккурат 156 байт. Теперь его надо прчитать и вот тут начинается гемморой:
myVector пока пуст, пишу in.read((char *) &myVector, 156); cout<<myVector.size(); myObject = myVector[0]; И начинается попа - валится access violation, Неудивительно... читаешь-то поперек памяти. плюс какой то debug error damage in heap assert тебе практически прямым текстом предлагает взять дебаггер. и прочие яйца Тараканы в голове - первая причина появления граблей.
|
|
|
Записан
|
У меня дикая аллергия на тупость. Я сразу покрываюсь сарказмом.
|
|
|
MadEd
http://facebook.com/fb.stas
Гродненец
Репутация: +11/-0
Offline
Пол:
Сообщений: 266
Permanently drunk...
|
Да видите ли - я в Сях как китаец в истории Беларуси [не]разбираюсь, так получилось что прыгнул сразу в Java, а там так жёстко за памятью следить не надо, привык а теперь вот мучаюсь. Дебаггером пользовался, но чего то понятного для себя не добился. Если Вас не затруднит о великий Арчи не могли бы поподробнее - и мой респект к Вам станет ещё более запредельным, чем сейчас. Спасибо А тараканов у меня в голове действительно хватает
|
|
|
Записан
|
|
|
|
iced
Гость
|
1. поперёк памяти - это как? 2. у тебя много чего не правильно. почитай умную книжку какую. алена голуба про верёвку например.
|
|
|
Записан
|
|
|
|
Archi
|
1. поперёк памяти - это как? Это мимо.
|
|
|
Записан
|
У меня дикая аллергия на тупость. Я сразу покрываюсь сарказмом.
|
|
|
Archi
|
in.read((char *) &myVector, 156); И где проверка на кол-во считанных байт? cout<<myVector.size(); А какой результат дает эта строка? myObject = myVector[0]; Видимо, вызывается копи-конструктор? Или это хитрое недоступное непосвященным жонглирование указателями? Я таки понимаю, что нас небезосновательно считают телепатами, но поверьте, приходится тщательно скрывать свои таланты.
|
|
|
Записан
|
У меня дикая аллергия на тупость. Я сразу покрываюсь сарказмом.
|
|
|
iced
Гость
|
2Archi: ты тоже подумай немного что у него не так ;]
|
|
|
Записан
|
|
|
|
Archi
|
2Archi: ты тоже подумай немного что у него не так ;] Не хочу. Кошмары будут сниться. А по сути каждый человек учится только на своих ошибках.
|
|
|
Записан
|
У меня дикая аллергия на тупость. Я сразу покрываюсь сарказмом.
|
|
|
Mишкa (Phantom)
|
У меня вот это замечательно работает, без всяких access violation... #include <iostream> #include <fstream> #include <vector>
using namespace std;
struct myStr { int a; string b; string c; };
int main() { vector<myStr> myVector; ofstream out("buf.txt", ios::out); ifstream in("buf.txt", ios::in); int size;
myStr myObject;
myObject.a = 1; myObject.b = "string 1"; myObject.c = "string 2";
myVector.push_back(myObject); myObject.a = 2; myVector.push_back(myObject); out.write((char*) &myVector, sizeof(myObject) * myVector.size()); size = sizeof(myObject) * myVector.size(); out.close();
//Для чистоты эксперимента myVector.empty();
in.read((char *) &myVector, size); std::cout<<myVector.size(); myObject = myVector[0];
return 0; }
P.S. Проверки не делал :-). Хотя, не мешало бы...
|
|
« Последнее редактирование: 07 Июнь 2005, 17:17:05 от Phantom »
|
Записан
|
|
|
|
iced
Гость
|
>in.read((char *) &myVector, size);
ну ну. удачи.
|
|
|
Записан
|
|
|
|
MadEd
http://facebook.com/fb.stas
Гродненец
Репутация: +11/-0
Offline
Пол:
Сообщений: 266
Permanently drunk...
|
to Phantom: у тя тут частный случай. Представь, что файл уже есть, а myVector просто объявлен, тогда не работает.
to All как альтернативный вариант возможно ли следующее - элементы вектора запердоливать в файл как строки, потом их читать и добавлять в него push_back'ом ? В связи с этим вопрос читаем то мы как char* а в вектор нуна послать myType, получается нужно перегружать под свои нужды приведения типов или я не прав?
Если кого не затруднит скажите ещё и следующее - как вектор размещается в памяти? так же как и обычный массив или как-то по другому
Если в векторе 10 элементов по 1 байту, значит ли это что он занимает в памяти 10 байт или он ещё что-то отъедает под свою внутреннюю структуру?
Заранее всем благодарен, Фантому - особливо, хоть за какую то конкретику
|
|
|
Записан
|
|
|
|
Archi
|
Если кого не затруднит скажите ещё и следующее - как вектор размещается в памяти? так же как и обычный массив или как-то по другому Читать Липпмана.
|
|
|
Записан
|
У меня дикая аллергия на тупость. Я сразу покрываюсь сарказмом.
|
|
|
Mишкa (Phantom)
|
>in.read((char *) &myVector, size);
ну ну. удачи. Спасибо за пожелание... Загадками не говори. Скажи конкретно, "умник". Если знаешь что-то, чего другие не знают, то поделись этим. Если не хочешь ничего толкового сказать - сиди и молчи в тряпочку.
|
|
|
Записан
|
|
|
|
Mишкa (Phantom)
|
to Phantom: у тя тут частный случай. Представь, что файл уже есть, а myVector просто объявлен, тогда не работает.
Попрбуй получить размер файла (в моем случае - 120 байт. Точно такое же значение получается size = sizeof(myObject) * myVector.size(); ) to Phantom: to All как альтернативный вариант возможно ли следующее - элементы вектора запердоливать в файл как строки, потом их читать и добавлять в него push_back'ом ? В связи с этим вопрос читаем то мы как char* а в вектор нуна послать myType, получается нужно перегружать под свои нужды приведения типов или я не прав?
Моя немного не понимать что хотеть делать? to Phantom: Если кого не затруднит скажите ещё и следующее - как вектор размещается в памяти? так же как и обычный массив или как-то по другому
Если в векторе 10 элементов по 1 байту, значит ли это что он занимает в памяти 10 байт или он ещё что-то отъедает под свою внутреннюю структуру?
У меня в векторе 2 элемента по 60 байт - в памяти они занимают 120 байт (размер файла такой же). Можно предположить, что 10 по 1 = 10 байт. Если что не так, звиняйте.
|
|
« Последнее редактирование: 08 Июнь 2005, 15:39:18 от Phantom »
|
Записан
|
|
|
|
MadEd
http://facebook.com/fb.stas
Гродненец
Репутация: +11/-0
Offline
Пол:
Сообщений: 266
Permanently drunk...
|
Читать Липпмана Спасибо, уже скачал - хорошая книжка Спасибо за пожелание... Загадками не говори. Скажи конкретно, "умник". Если знаешь что-то, чего другие не знают, то поделись этим. Если не хочешь ничего толкового сказать - сиди и молчи в тряпочку. В этом весь IceD, я уже привык. Развитое абстрактное мышление соответственно влияет и на способность выражать свои мысли конкретнее, а точнее убивает эту способность Моя немного не понимать что хотеть делать? А моя уже поняла, что делала всё не так! Когда мы пишем vector<myType> myVector, то под него ничего не отводится, поэтому read пишет байты хер знает куда (или я опять промахнулся со своими догадками?) Следовательно необходимо: 1. Чтобы в файле элементы вектора шли не в одну сплошную строку, а построчно 2. При чтении файла узнать скока там этих элементов 3. Отвести необходимые мозги под вектор из этих n элементов 4. Считать элемент(строку) и push_back' нуть его в вектор НО!!! При чтении строки в буффер мы имеем char* поэтому надо придумать как сделать его myType Вопрос: в чём я не прав? Если можно проще то намекните Эх, а в Джаве есть такая херь как сериалайзабл да и с приведением типов там на много проще... [smiley=yes.gif]
|
|
|
Записан
|
|
|
|
iced
Гость
|
>Загадками не говори. Скажи конкретно, "умник". Если знаешь что-то, чего другие не знают, то поделись этим. Если не хочешь ничего толкового сказать - сиди и молчи в тряпочку.
для тех кто ленится думать сам расшифровываю. std::vector при создании резирвирует место под неготорое кол-во элементов. если кол-во в файле у тебя меньше - то всё ок, если больше - то будет очень весело. за такой код убивать надо сразу.
PS. кто мешает >> и << использовать?
|
|
|
Записан
|
|
|
|
Mишкa (Phantom)
|
Да, с выделением памяти я, мягко говоря, немножко лоханулся.. :-) Отвык уже от великого и могучего C++. Это все .NET виноват... Расслабляет со своим мусоросжигателем. :-)
|
|
|
Записан
|
|
|
|
MadEd
http://facebook.com/fb.stas
Гродненец
Репутация: +11/-0
Offline
Пол:
Сообщений: 266
Permanently drunk...
|
Да уж Джава и дотНет портят программистов, делая из них девелоперов, но всё равно Garbage collector - рулит! [smiley=2.gif]
|
|
|
Записан
|
|
|
|
Mишкa (Phantom)
|
2MadEd: >> При чтении строки в буффер мы имеем char* поэтому надо придумать как сделать его myType А ты тупо приводи все к стрингу и пиши в текстовый файл построчно (каждый элемент структуры пишешь в отдельную строку в текстовом режиме ). При чтении делай обратное преобразование 1-я строка к int, 2-я и 3-я - без изменений. кол-во элементов получаешь как {кол-во строк/3} Затем myObject.a = param1 {переконверченное в интегер}; myObject.b = param2; myObject.c = param3; myVector.push_back(myObject);
им понеслась... В бинарных файлах, IMHO, нет понятия строки, там сплошной поток байтиков... :-) пока больше предложить ничего не могу. Звиняйте.
|
|
« Последнее редактирование: 08 Июнь 2005, 21:18:36 от Phantom »
|
Записан
|
|
|
|
ghostWhite
|
Ой трудный день сегодня был и если что простите 1. Так злобно обходится с STL Vector (далее просто вектор) как вы, абсолютно нельзя, ну совсем нельзя. Помимо ваших любимых данных вектор содержит ну просто кучу всяких вспомогательных вещей начиная от аллокатора и заканчивая итераторами. Поэтому такая запись: out.write((char*) &myVector, sizeof(myObject) * myVector.size()); мягко говоря наивна. Записаться то он запишется, но ожидать что после: in.read((char *) &myVector, size); или in.read((char *) &myVector, 156); вы получите готовый объект класса std::vector мягко говоря верх наивности. 2. Если вы таки хотите сохранить содержимое вектора в двоичном файле, то делается это поэлементно и никак иначе. Для этого существуют итераторы и алгоритм for_each. 3. Если вы хотите сохранить некий сложный составной объект в файле то это опять же делается поэлементно. Т.е. вы сохраняете каждое поле вашего объекта поэлементно. И никак иначе. Если вы хотите красиво применить это в сочетании с пунктом 2 то для этого вам надо правильно перегрузить операторы << и >>. Тогда после этого вы сможете счастливо написать такое: some_output_stream << my_complex_object; some_input_stream >> my_complex_object; 4. STL строка, как это ни странно, тоже сложный объект и перед его сохранением в двоичный файл вместе с элементами других типов надо немного подумать головой. 5. Для того что бы правильно прочитать массив элементов из файла не мешало бы знать размер этого самого элемента и их количество перед операцией чтения. 6. C++ это не Java. Здесь нет понятия сериализации типа данных на уровне языка (в принципе и в Java не всё так радужно). Если вам нужна эта самая сериализация то придётся делать её ручками.
|
|
|
Записан
|
Не будите во мне зверя, он и так всё время не высыпается
|
|
|
iced
Гость
|
2ghostWhite: хотел вот какую нить гадость написать - а придраццо то и некчему ;]
|
|
|
Записан
|
|
|
|
MadEd
http://facebook.com/fb.stas
Гродненец
Репутация: +11/-0
Offline
Пол:
Сообщений: 266
Permanently drunk...
|
>to ghostWhite: Огромнейшее спасибо и такой же тебе респект, Учитель. Я до этого уже почти и сам додумался, благо коллеги по работе знают С++ получше моего - объяснили, что к чему в этой жизни to ALL: Господа! Будьте терпимее друг к другу, "гуру" не рождаются, и если можете и ХОТИТЕ помочь (тем более, когда Вас об этом просят) - помогайте и будет Вам счастье. А если не хотите, то лучше прямо использовать отсылательно-посылательную конструкцию Великого и Могучего русского языка, а не терять время на пространные соображения по поводу автора вопроса и его скилов, это автор и без Вас знает Всем спасибо, все свободны, НО тема исчерпана лишь в частном контексте...
|
|
|
Записан
|
|
|
|
|