Ошибка в использовании CArray

 
0
 
C++
ava
it_medved | 01.05.2007, 20:14
Пожалуйста, помогите найти ошибку в коде!

    CTovar tmp_tov;
    CGroupTovar* group = new CGroupTovar();
    group = (CGroupTovar*) m_ctrlComboBox.GetItemData(m_ctrlComboBox.GetCurSel());
    for(INT_PTR i=0; i<group->group_tovar.GetSize(); i++)//Вылетает здесь!
    {
        tmp_tov = group->group_tovar.GetAt(i);
        m_crrlListBox.AddString(tmp_tov.name);
    }

CTovar - мой класс, CGroupTovar - класс, в котором инициализирован массив CTovar - CArray <CTovar> group_tovar. По субьективным ощущениям, ошибка в безобидной функции GetSize
Ответы (13)
ava
zkv | 01.05.2007, 20:23 #
Цитата (it_medved @  1.5.2007,  19:14 findReferencedText)
    group = (CGroupTovar*) m_ctrlComboBox.GetItemData(m_ctrlComboBox.GetCurSel());


а вы в комбо бокс положили предварительно что нить? посмотрите что возвращает  GetItemData(), здесь ошибка!

ps в msdn загляните.

ой-ой-ой, не доглядел сразу, а это что за:

CGroupTovar* group = new CGroupTovar();
перед

group = (CGroupTovar*) m_ctrlComboBox.GetItemData(m_ctrlComboBox.GetCurSel());
 
можете объяснить, что у вас здесь происходит?
ava
it_medved | 02.05.2007, 00:14 #
CGroupTovar* group = new CGroupTovar(); - это я выделяю динамическую память
И предварительно я в CCOmboBox запихнул переменную типа CGroupTovar, тут все впорядке... вроде
ava
zkv | 02.05.2007, 00:36 #
Попробуем разобраться:

//выделили память в размере sizeof(CGroupTovar)
CGroupTovar* group = new CGroupTovar();
//благополучно "потеряли" память в размере sizeof(CGroupTovar), зачем выделяли?
group = (CGroupTovar*) m_ctrlComboBox.GetItemData(m_ctrlComboBox.GetCurSel());

Цитата (it_medved @  2.5.2007,  00:14 findReferencedText)
И предварительно я в CCOmboBox запихнул переменную типа CGroupTovar, тут все впорядке... вроде 

давайте иллюстрировать мысли кодом smile Как запихивали?
ava
it_medved | 02.05.2007, 00:44 #
Вот так и запихнул, а как еще?
    CGroupTovar* computers;
    computers = new CGroupTovar();
    m_ctrlComboBox.SetItemData(1,(DWORD)computers);

Добавлено позднее:
Кстати, я уже реализовал всю ту белиберду с помощью CList, было сложнее, но зато работает...
Но все равно хочется узнать, в чем же была ошибка. Кстати, вот эта же переделанная программа... готовтесь.. :)


CTovar* tovar;
    CTovar *ctrl_tmp = new CTovar();
    CString select_name;
    m_ctrl_CListBox.GetText(m_ctrl_CListBox.GetCurSel(),select_name);
    POSITION pos = list_tovar.GetHeadPosition();
    for(int i=0; i<list_tovar.GetCount(); i++)
    {
        *ctrl_tmp = list_tovar.GetNext(pos);
        if(ctrl_tmp->m_str_name != select_name)
        {
            ctrl_tmp->SetData("Французкие духи","15 евро/грамм","очень пахучие духи");
            m_strEditProper = ctrl_tmp->GetData_Tovar();
            UpdateData(FALSE);
            return;
        }
        else
            m_strEditProper = "";
    }
    //tovar = (CTovar*) m_ctrl_CListBox.GetItemData(m_ctrl_CListBox.GetCurSel());
    UpdateData(FALSE);
ava
Earnest | 02.05.2007, 13:35 #
zkv уже сказал, в чем ошибка: сначала выделяешь динамически переменную, потом тут же теряешь память и уже навсегда. Хотя эту ошибку (утечки памяти) ты еще, похоже, не обнаружил. Но она есть.

Цитата (it_medved @  2.5.2007,  01:44 findReferencedText)
 CGroupTovar* computers;
     computers = new CGroupTovar();
     m_ctrlComboBox.SetItemData(1,(DWORD)computers);


То же самое, только сбоку.
Какой смысл запихивать пустой, только что созданный элемент в данные комбобокса?
Ты же список товаров не в комбобоксе хранишь, надо полагать. Тебе нужно просто связать элементы списка с элесентами комбобокса.

Через LIST, ты, кстати, сделал совсем по другому - не вижу, где в комбобокс-итемы пихаешь данные. Но утечка памяти все равно есть.

Даже если очень хорошо понимаешь, что происходит (что в данном случае явно не так) не стОит помещать в данные комбобокса и прочих окон указатели на динамически выделенные данные. За ними весьма утомительно следить, когда они преобразованы не в свой тип (в данном случае,  int). При любых телодвижениях (удалении элементов из списка-окна и т.д.) нужно иметь в виду динамическую природу этих данных. Но, похоже, тебя вообще вопросы очистки пока не волнуют. Но это только пока.

Гораздо лучше в данные окна помешать что-нибудь безобидное - например, индексы элементов массива, который хранится в нормальном виде в совсем другом месте.
Или указатели на элементы списка (но не динамические, конечно).

Судя по коду, ты упорно пытаешься выделить память для указателя.
НЕ НАДО!
ava
it_medved | 02.05.2007, 15:20 #
А мне кажется ,что надо выделять дин память только потому, что в SetItemData принимает только динамические переменные, но вы правы, в CList я сделал совсем по другому, просто в к CComboBox прикрепляю CString

Добавлено позднее:
P.S. - Интересно, а как же я это все написал, если не очень понимаю что пишу? Кстати с CList все работает
ava
Greeen | 02.05.2007, 15:26 #
Цитата (it_medved @  2.5.2007,  00:44 findReferencedText)
*ctrl_tmp = list_tovar.GetNext(pos);

а это как понимать?
ava
it_medved | 02.05.2007, 15:48 #
А вот так и понимать, получаю данные типа CTovar со следующего елемента списка, предварительно разименовав переменную, что бы по значению присвоить
ava
Greeen | 02.05.2007, 16:01 #
Зачем вообще выделять память под tovar, если у тебя объекты и так хранятся в списке. Лишнее выделение памяти, копирование объекта, да еще и память не освобождаешь.
ava
zkv | 02.05.2007, 16:01 #
Цитата (it_medved @  2.5.2007,  15:20 findReferencedText)
P.S. - Интересно, а как же я это все написал, если не очень понимаю что пишу? Кстати с CList все работает

это и впрямь удивительно smile
ava
it_medved | 02.05.2007, 16:21 #
Я начинаю сначала эту программу уже в третий раз, вот так, мне кажется, будет самое чучшее -

POSITION pos = one_group.list_tovar.GetHeadPosition();
    CTovar tovar;

    one_group.m_str_GROUPNAME = "Видеокарты";
    m_ctrlComboBox.AddString(one_group.m_str_GROUPNAME);

    one_group.list_tovar.AddHead(CTovar());
    tovar = one_group.list_tovar.GetHead();
    tovar.SetData("nVidia 8800GT","256/128","155");

    one_group.list_tovar.AddHead(CTovar());
    tovar = one_group.list_tovar.GetHead();
    tovar.SetData("nVidia 8800GTS","320/384","350");

Все просто, доступно, и прикреплять к ComboBox ничего небуду, буду обрабатывать событие клика, и если имя группы совпадет с названием строки (а я так сделал в InitDialog) - вуаля, и буду выводить информацию о продукте!
ava
Greeen | 02.05.2007, 17:56 #
it_medved, зачем ты себе жизнь усложняешь???

one_group.m_str_GROUPNAME = "Видеокарты";
m_ctrlComboBox.AddString(one_group.m_str_GROUPNAME);
CTovar tovar;
tovar.SetData("nVidia 8800GT","256/128","155");
one_group.list_tovar.AddHead(tovar);
tovar.SetData("nVidia 8800GTS","320/384","350");
one_group.list_tovar.AddHead(tovar);
ava
it_medved | 05.05.2007, 15:13 #
Тема исчерпала интересность smile
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
  Earnest   zkv   Greeen   it_medved
advanced
Отправить