СArray
От: Xenia США  
Дата: 04.04.02 17:06
Оценка:
Здравствуйте!
Имеется такой код:

struct Info{
    CString razd;
    CString stroka;
};
CArray<Info,Info> nastr;
//и две фуекции - одна создает файл а другая затем его читает
void CNastr::CreateFile()
{
    Info inf;
    CFile file("nastr.nas", CFile::modeWrite | CFile::modeCreate);
    CArchive ar(&file, CArchive::store);
    int ArSize=nastr.GetSize();
    ar.Write(&ArSize,sizeof(int));
    for (int i=0;i<ArSize;i++)
    {
    inf = nastr.GetAt(i);
    ar.Write(&inf,sizeof(Info));
    }
    ar.Close();
    file.Close();
}

void CNastr::Init()
{
   CFile file("nastr.nas", CFile::modeRead);
   CArchive ar(&file, CArchive::load);
   int ArSize;
   Info inf=new Info;
   ar.Read(ArSize,sizeof(int));
   for (int i=0;i<ArSize;i++)
   {
      ar.Read(inf,sizeof(Info));
      nastr.Add(inf);
   }
   ar.Close();
   file.Close();
}

При чтении файла вываливается Assertion Failed, File dbgheap.c Line 1011 Expression _CrtlsValidHeapPointer(pUserData)
Чего ему не хватает :???:
Пробовала выделять память динамически, но это не помогает.
Re: СArray
От: Курилка Россия http://kirya.narod.ru/
Дата: 04.04.02 17:17
Оценка:
Здравствуйте Xenia, Вы писали:

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

X>Имеется такой код:

X>
X>struct Info{
X>    CString razd;
X>    CString stroka;
X>};
X>CArray<Info,Info> nastr;
X>//и две фуекции - одна создает файл а другая затем его читает
X>void CNastr::CreateFile()
X>{
X>    Info inf;
X>    CFile file("nastr.nas", CFile::modeWrite | CFile::modeCreate);
X>    CArchive ar(&file, CArchive::store);
X>    int ArSize=nastr.GetSize();
X>    ar.Write(&ArSize,sizeof(int));
X>    for (int i=0;i<ArSize;i++)
X>    {
X>    inf = nastr.GetAt(i);
X>    ar.Write(&inf,sizeof(Info));
X>    }
X>    ar.Close();
X>    file.Close();
X>}

X>void CNastr::Init()
X>{
X>   CFile file("nastr.nas", CFile::modeRead);
X>   CArchive ar(&file, CArchive::load);
X>   int ArSize;
X>   Info inf=new Info;
X>   ar.Read(ArSize,sizeof(int));
X>   for (int i=0;i<ArSize;i++)
X>   {
X>      ar.Read(inf,sizeof(Info));
X>      nastr.Add(inf);
X>   }
X>   ar.Close();
X>   file.Close();
X>}
X>

X>При чтении файла вываливается Assertion Failed, File dbgheap.c Line 1011 Expression _CrtlsValidHeapPointer(pUserData)
X>Чего ему не хватает
X>Пробовала выделять память динамически, но это не помогает.

ну ты посмотри, что у тебя происходит:
ты пишешь Info, а в нём 2 строки, которые есть лишь место под вспом. переменные для строки (сами строки динамически получаются, там указатели). Надо сделать типа

clas Info{
 CString razd;
 CString stroka;
}

CArchive& operator <<( CArchive& ar, const Info& info ){
  return ar << info.razd << info.stroka;
};

CArchive& operator >>( CArchive& ar, const Info& info ){
  return ar >> info.razd >> info.stroka;
};

//в CNastr::CreateFile()
ar >> inf;

//в CNastr::Init()
ar << inf;


и всё должно быть пучком! (Надеюсь...)
Re[2]: СArray
От: Xenia США  
Дата: 04.04.02 17:47
Оценка:
Извиняюсь за тупость, но можно разяснить, где писать

CArchive& operator <<( CArchive& ar, const Info& info ){
  return ar << info.razd << info.stroka;
};

CArchive& operator >>( CArchive& ar, const Info& info ){
  return ar >> info.razd >> info.stroka;
};

Определить класс-потомок от CArchive и в нем перегрузить эти операторы?
Re[3]: СArray
От: Курилка Россия http://kirya.narod.ru/
Дата: 04.04.02 17:58
Оценка:
Здравствуйте Xenia, Вы писали:

X>Извиняюсь за тупость, но можно разяснить, где писать


X>
X>CArchive& operator <<( CArchive& ar, const Info& info ){
X>  return ar << info.razd << info.stroka;
X>};

X>CArchive& operator >>( CArchive& ar, const Info& info ){
X>  return ar >> info.razd >> info.stroka;
X>};

X>

X>Определить класс-потомок от CArchive и в нем перегрузить эти операторы?

Нет, не надо никаких доп. классов, это глобальные операторы(вне всяких классов).
Re: СArray так, к слову...
От: Shergin Россия http://shergin.com/
Дата: 04.04.02 19:23
Оценка:
Здравствуйте Xenia, Вы писали:

X>CArray<Info,Info> nastr;


А в какой-то книжке рекомендовали писать

CArray<Info,&Info> nastr;

Я не думаю что у Вас в этом проблема...
Просто интересно в чем разница...

ЗЫ: А слово "фуекции" мне понравилось!!!
ЗЗЫ: А что, эта прога настроением управляет???
Валентин Шергин
http://shergin.com/
Re[4]: СArray
От: Xenia США  
Дата: 05.04.02 07:16
Оценка:
Я поняла в чем проблема... Мы не знаем заранее размер CString. Поэтому я от него отказалась и использую char[9], тем более что у меня длина всегда фиксированная. Так что проблему успешно опборола. Кстати, мой компилятор ругается на переопределение оператора >> — говорит нет соответствующего с правым операндом типа CString.
Re[5]: СArray
От: Курилка Россия http://kirya.narod.ru/
Дата: 05.04.02 07:37
Оценка:
Здравствуйте Xenia, Вы писали:

X>Я поняла в чем проблема... Мы не знаем заранее размер CString. Поэтому я от него отказалась и использую char[9], тем более что у меня длина всегда фиксированная. Так что проблему успешно опборола. Кстати, мой компилятор ругается на переопределение оператора >> — говорит нет соответствующего с правым операндом типа CString.


Совершенно верно ты поняла
А ругается, потому, что я из ума писал и забыл, что в >> для параметра Info const нафиг не нужен (ну меняется же он!), убери его и всё будет замечательно, хотя если у тебя строки фиксированные, то, конечно, это тебе не очень-то и нужно...
Хорошего тебе настроения !
Re[5]: СArray
От: Bell Россия  
Дата: 05.04.02 07:45
Оценка:
Здравствуйте Xenia, Вы писали:

X>Я поняла в чем проблема... Мы не знаем заранее размер CString. Поэтому я от него отказалась и использую char[9], тем более что у меня длина всегда фиксированная. Так что проблему успешно опборола. Кстати, мой компилятор ругается на переопределение оператора >> — говорит нет соответствующего с правым операндом типа CString.


Просто для CArchive не определен оператор >> для типа CString, но если очень хочется, то можно определить свой...
Но я хочу сказать несколько о другом — в функции CArchive::Write ты используешь sizeof(Info), а результат sizeof, вообще говоря, зависит от выравнивания. Поэтому теоретически возможна ситуация, когда записывается одно количество байт, а считывется другое, что не есть хорошо.
Поэтому я бы объявил структуру Info так:


#pragma pack(1)//Или не 1, а что-нибудь другое...
struct Info
{
    char razd[9];
    char stroka[9];
};
#pragma pack()



В этом случае sizeof(Info) всегда одно и тоже.
Еще раз повторюсь — вероятность такого рода сбоя не очень велика, но она существует.
В частности, я столкнулся с такой проблемой, когда обрабатывал бинарные файлы, созданные другим приложением (хотя и в том, и в другом приложении использовались одни и те же структуры...)
Любите книгу — источник знаний (с) М.Горький
Re[6]: СArray
От: Курилка Россия http://kirya.narod.ru/
Дата: 05.04.02 07:52
Оценка:
Здравствуйте Bell, Вы писали:

B>Здравствуйте Xenia, Вы писали:


X>>Я поняла в чем проблема... Мы не знаем заранее размер CString. Поэтому я от него отказалась и использую char[9], тем более что у меня длина всегда фиксированная. Так что проблему успешно опборола. Кстати, мой компилятор ругается на переопределение оператора >> — говорит нет соответствующего с правым операндом типа CString.


B>Просто для CArchive не определен оператор >> для типа CString, но если очень хочется, то можно определить свой...


Не — враки, определён, там проблема в другом была (см. мессагу выше), а за напоминание за прагму спасибки — может тоже когда-нибудь на грабли наступлю...
Re[2]: Re: Array
От: grigsoft Беларусь http://www.grigsoft.ru/
Дата: 05.04.02 08:36
Оценка:
Привет!
Xenia, если в будующем Вы все же соберетесь использовать CArray со строками (или другими структурами),
надо для структуры написать оператор присваивания, т.к. CArray внутри вызывает его при копировании.
Нечто вроде

struct Info
{
CString razd;
CString stroka;
Info& operator=(const Info&);
};
Info& Info::operator=(const Info& a)
{
razd = a.razd;
stroka = a.stroka;
return *this;
}

CArray<Info,Info> nastr;
Re[2]: Re: СArray так, к слову...
От: grigsoft Беларусь http://www.grigsoft.ru/
Дата: 05.04.02 08:41
Оценка:
Здравствуйте Shergin, Вы писали:

S>А в какой-то книжке рекомендовали писать


S>CArray<Info,&Info> nastr;


На самом деле рекомендуют писать
CArray<Info,Info&> nastr;

При этом в операции nastr[i]=obj; не будет создаваться лишний промежуточный объект.

Игорь
Re[3]: Re: Array
От: Xenia США  
Дата: 05.04.02 09:56
Оценка:
Здравствуйте grigsoft, Вы писали:

G>Привет!

G>Xenia, если в будующем Вы все же соберетесь использовать CArray со строками (или другими структурами),
G>надо для структуры написать оператор присваивания, т.к. CArray внутри вызывает его при копировании.
G>Нечто вроде

G>struct Info

G>{
G> CString razd;
G> CString stroka;
G> Info& operator=(const Info&);
G>};
G>Info& Info::operator=(const Info& a)
G>{
G> razd = a.razd;
G> stroka = a.stroka;
G> return *this;
G>}

G>CArray<Info,Info> nastr;

Спасибо, я это уже поняла. Но по-моему надо определить еще конструктор копий. Или я ошибаюсь?
Re[4]: Re: Array
От: grigsoft Беларусь http://www.grigsoft.ru/
Дата: 05.04.02 10:16
Оценка:
G>>Привет!
G>>Xenia, если в будующем Вы все же соберетесь использовать CArray со строками (или другими структурами),
G>>надо для структуры написать оператор присваивания, т.к. CArray внутри вызывает его при копировании.

X>Спасибо, я это уже поняла. Но по-моему надо определить еще конструктор копий. Или я ошибаюсь?


Нет необходимости — CArray его не использует. Разве что для красоты :-)
Кстати, не стесняйтесь заглядывать в исходники CArray и всего MFC — многое становиться понятно именно там.

Уже после своего ответа присмотрелся к Вашему коду и понял, что он (мой ответ) был не в тему — настоящую проблему указал Курилка, так что извините. Уже все работает? А то заполнение массива выделенными new элементами даже компилироваться, по идее, не должно :-)

Вообще, сваливать таким образом данные на диск не очень красиво. Что Вы будете делать когда завтра понадобиться добавить в info еще одно поле? А если Вы просто захотите добавить виртуальные функции к info, тогда измениться размер структуры и file.write(&info, sizeof(info)) потеряет смысл. Хотя, конечно, если это разовая работа, то заморачиваться такими вещами смысла действительно нет. А вот чтобы в "люди выйти" :-) привычка к хорошему стилю может пригодиться.

Удачи,

Игорь
Re[5]: Re: Array
От: Xenia США  
Дата: 05.04.02 16:17
Оценка:
G>Вообще, сваливать таким образом данные на диск не очень красиво. Что Вы будете делать когда завтра понадобиться добавить в info еще одно поле? А если Вы просто захотите добавить виртуальные функции к info, тогда измениться размер структуры и file.write(&info, sizeof(info)) потеряет смысл. Хотя, конечно, если это разовая работа, то заморачиваться такими вещами смысла действительно нет. А вот чтобы в "люди выйти" привычка к хорошему стилю может пригодиться.
Удачи,
G>Игорь
Вообще-то назначение структуры Info у меня это всего-лишь установление соответствия между определнным Edit'ом в моей программе и префиксом строки в текстовом файле, так что в ней не может быть вообще никаких функций. Именно поэтому она struct а не class
Re[6]: Re: Array
От: Аноним  
Дата: 05.04.02 16:32
Оценка:
А по мне так записывать на диск объекты классов вообще, как бы это сказать, не люблю я этого. Лучше определьтся с форматом, и записывать в этом формате, чем надеятся на то, что эта информация будет использоваться только через определенный класс, что этот класс никогда не поменяется, и что он не содержит никаких динамических данных.
Re[7]: Re: Array
От: grigsoft Беларусь http://www.grigsoft.ru/
Дата: 05.04.02 17:03
Оценка:
А>А по мне так записывать на диск объекты классов вообще, как бы это сказать, не люблю я этого. Лучше
> определьтся с форматом, и записывать в этом формате, чем надеятся на то, что эта информация будет
> использоваться только через определенный класс, что этот класс никогда не поменяется, и что он не
> содержит никаких динамических данных.

Тоже верно, особенно в описанном Xenia случае. И формат уже изобретен — XML :-)

To Xenia: а между class и struct разницы никакой — записи
struct A {int i;};
и
class A{public: int i;};
абсолютно эквивалентны.

Ну да ладно, топик на этом предлагаю считать исчерпаным :-)

Игорь
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.