Странное нарушение доступа у векторного индексатора - PullRequest
1 голос
/ 05 июля 2011

Сначала несколько введений: я сейчас работаю над совместимостью с C ++, что означает возможность запускать проекты с разными параметрами компилятора друг с другом.Поэтому я тестирую с помощью Release DLL и приложения Debug, связанного с этим другим проектом.Большинство проблем возникает при использовании STL, поэтому я должен заверить, что оба проекта используют только свою собственную версию STL.Вот почему у меня есть класс-оболочка, который может быть собран из std :: vectors, std :: lists и т. Д., Но содержит только полностью совместимый массив.Теперь я могу обернуть значения в массиве и распаковать их с другой стороны в действительный объект STL.

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

Создание этого класса-оболочки вовсе не проблемано распаковка приводит к нарушению прав доступа в векторном классе прямо здесь:

   const_reference operator[](size_type _Pos) const
        {   // subscript nonmutable sequence

 #if _HAS_ITERATOR_DEBUGGING
        if (size() <= _Pos)
            {
            _DEBUG_ERROR("vector subscript out of range");
            _SCL_SECURE_OUT_OF_RANGE;
            }
 #endif /* _HAS_ITERATOR_DEBUGGING */
        _SCL_SECURE_VALIDATE_RANGE(_Pos < size());

        return (*(_Myfirst + _Pos));  <---- HERE
        }

Код, выполняемый в этот момент, таков:

template<class T>
struct mwContainerItem
{
    T m_element;
    void * m_tag;
};

template<class T>
class mwContainer
{
    STLList ToList()
    {
        STLList l;
        for(size_t i=0; i<m_size; ++i) <---- It crashes when accessing m_size
        {
            l.push_back(m_elements[i].m_element); <---- It also crashes when accessing m_elements
        }
        return l;
    }

    mwContainerItem<T>* m_elements;
    size_t m_size;
};

Любопытно, что это яЯ распаковываю std :: list, но он падает в std :: vector.Если посмотреть, то у меня есть класс, содержащийся в std :: vector, и этот класс содержит std :: список некоторого базового класса без STL.Таким образом, распаковка означает копирование внешнего массива в std :: vector и каждого внутреннего массива в std :: list.

Эта ошибка возникает только тогда, когда я использую различные параметры компилятора, упаковывая и распаковывая в одном и том же проекте.работает просто отлично.

Я действительно надеюсь, что кто-нибудь может мне помочь, потому что я понятия не имею.

С уважением

1 Ответ

1 голос
/ 05 июля 2011

Вам действительно нужны две версии STL? Я имею в виду, вы строите два проекта с двумя разными компиляторами и двумя разными реализациями STL? При смешивании версий отладки и выпуска проблема обычно возникает из-за наличия двух разных куч. Тогда попытка освободить память, выделенную в одном модуле в другом, приведет к ошибке. Если это тот случай, с которым вы сталкиваетесь, вы можете попробовать другой подход - использовать обе кучи.

Если у вас есть контроль над обоими проектами, вы можете экспортировать распределитель (и соответствующий освобождающий элемент) из DLL и использовать его в EXE-файле. Таким образом, управление памятью будет осуществляться в одной куче, и тип сборки не будет иметь значения. Вы можете использовать его в операторе new , в распределителе векторов / списков и т. Д.

Это, вероятно, не решит проблемы с упаковкой (кто вообще меняет настройки упаковки? ...), но это то, что вам нужно при использовании более чем одной кучи.

...