Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Загадочное поведение кода (MFC / CArray / vector)  (Прочитано 11129 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алик
Постоялец

kz
Offline Offline

« : 11-10-2011 07:02 » 

Добрый день!

Есть класс:
Код: (C++)
class CBytes : public std::vector<BYTE>
  {
  public:
    CBytes()
      {}

    CBytes(const CBytes& str)
      :std::vector<BYTE>(str.begin(), str.end())
      {
      }
    CBytes& operator= (const CBytes& str)
      {
      if (this != &str)
        {
        clear();
        insert(end(), str.begin(), str.end());
        }
      return *this;
      }
  };

И есть вот этот код:

Код: (C++)
CArray<CBytes , CBytes> testArray;
CBytes killme;
testArray.Add (CBytes ());
killme = testArray[0];
testArray.Add (CBytes ());
killme = testArray[0];
   

если запустить этот код в дебаговой конфигурации – программа падает на последней строчке этого кода killme = testArray[0]

Если конкретнее - падает внутри operator= на строке insert(end(), str.begin(), str.end());


кто может объяснить данный феномен?

У меня Visual Studio 2010, Windows 7 Pro 64

Пробовал в проекте MFC Dialog-based, Unicode
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 11-10-2011 07:30 » 

а где CArray то определён ?
Записан

Алик
Постоялец

kz
Offline Offline

« Ответ #2 : 11-10-2011 08:18 » 

это - стандартный МФЦшный класс
Записан
DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« Ответ #3 : 11-10-2011 14:39 » 

Алик,
поставь отладочные распечатки на что указывает str
в operator, проверку на NULL или посмотри в отладчике что там в памяти.
Результат insert.
CString cs1; cs1.Format("p=%p", str); AfxMessageBox(cs1);
где-то так.
Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 11-10-2011 15:42 » 

Алик, а кто заставляет им пользоваться ? Может там глюк. К примеру, в CFile есть глюк с поиском - самый первый файл не находится (первый - это такой же по счёту первый, как если бы пробовать найти файлы ::FindFirstFile)

Добавлено через 39 секунд:
Вообще, зачем смешивать контейнеры, пользуйся std::
« Последнее редактирование: 11-10-2011 15:43 от Алексей1153 » Записан

Алик
Постоялец

kz
Offline Offline

« Ответ #5 : 12-10-2011 04:46 » 

Алексей1153++, это - старый код. И у нас половина огромного проекта использует этот класс. Хотел разобраться в проблеме.

мне в общих чертах проблему объяснил коллега:
дело в том, что, когда добавляется второй элемент в CArray - происходит переаллокация памяти. при этом первый элемент переносится на новый адрес не через оператор=, а простым копированием памяти.
Майкрософтовская реализация вектора в качестве отладочной информации зачем-то хранит указатели на какие-то свои члены. И после копирования по новому адресу эти указатели становятся недействительными/сбойными.
В общем, CArray - зло.

Думаю, тему можно закрывать. Спасибо всем за ответы.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 12-10-2011 05:27 » 

Алик, переопредели класс CArray, если не хочется много проекта переписывать
Записан

Алик
Постоялец

kz
Offline Offline

« Ответ #7 : 12-10-2011 07:47 » 

Хмм... не, слишком глобально. Сеньоры не одобрят Улыбаюсь
Да и вообще, как можно стандартный класс МФЦ переопределить?! компилер же разноется
Записан
DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« Ответ #8 : 12-10-2011 08:17 » new

Алик,
("Пробовал в проекте MFC Dialog-based, Unicode ")
Отсади и попробуй в консольном запусти в main().
printf("\n\np=%p\n", &killme); итд
По крайней мере я твой код на VC6 пустил - не вешает, не вываливается.
Опции компилятора-линкера-проекта тоже стоит посмотреть-покрутить.


Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
Алик
Постоялец

kz
Offline Offline

« Ответ #9 : 12-10-2011 09:00 » 

DneprSMV, дык и у нас раньше подобного косяка не было (а проекту уже лет 20). В консольном приложении - та же история. Сейчас у нас ВижуалСтудия 2010. вероятно, что-то в МФЦ донаворотили в новой версии.

уже с этим ковыряться не будем. похоже, косяк вылазит только в дебаг-версии. решили в данном конкретном месте заменить CArray на vector и не париться Улыбаюсь
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 12-10-2011 10:39 » 

Хмм... не, слишком глобально. Сеньоры не одобрят Улыбаюсь
Да и вообще, как можно стандартный класс МФЦ переопределить?! компилер же разноется

так я предлагаю не класс менять, а по всему проекту заменить имя CArray на, скажем, CArrayWithBrain. Последний надо реализовать (как вариант - скопировать туда все исходники из CArray и исправить). Для совместимости с функциями MFC сделай оператор
operator const CArray&()



Добавлено через 1 минуту и 5 секунд:
решили в данном конкретном месте заменить CArray на vector и не париться Улыбаюсь
всё равно потом опять взорвётся где-нибудь Улыбаюсь
« Последнее редактирование: 12-10-2011 10:40 от Алексей1153 » Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines