В чем проблема повреждения кучи в конце программы в этой программе C ++? - PullRequest
0 голосов
/ 02 марта 2020

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

. Программа собирается прочитать двоичный файл заданной длины c и разделить его на подпакет, затем инициализировать правильный синтаксический анализатор для каждого подпакета и сохранить весь анализатор в очереди

ОБНАРУЖЕНА КОРРУПЦИЯ КАРТЫ: после блока Normal (# 182) в 0x005F2270. CRT обнаружил, что приложение записало в память после завершения буфера кучи.

int main()
    {
        deque<uint8_t> testData = { 0, 115, 0, 0, 1, 1, 0, 0, 0, 0, 0, 100 };
        deque < shared_ptr<IParser>> parsers;
        Splitter test(testData, parsers);
        test.split();
    }

класс Splitter

struct Splitter {
    const deque<uint8_t>& input;
    deque<shared_ptr<IParser>>& parsers;
    long x = 0;
    Splitter(const deque<uint8_t>& input, deque<shared_ptr<IParser>>& parsers) :input(input), parsers(parsers)
    {

    }

    deque<shared_ptr<IParser>> getParsers();
    bool split() {
        deque<uint8_t> newVec;
        auto headerparser = make_shared<HeaderParser>(newVec);
        parsers.push_back(headerparser);
        return true;
    }

};

класс IParser

struct IParser {
        const std::deque<uint8_t> input;
        IParser(const std::deque<uint8_t> input):input(input){} 
    };

и наконец HeaderParser

struct HeaderParser :public IParser
{
    shared_ptr<Header> output;
    HeaderParser(const deque<uint8_t>& input):IParser(input)
    {
      uint8_t* buff = (uint8_t*)&output;
      for (size_t i = 0; i < sizeof(Header); i++)
         buff[i] = 0;
     }
};

1 Ответ

3 голосов
/ 02 марта 2020
  uint8_t* buff = (uint8_t*)&output;

Эта строка неверна. Вы не конвертируете указатель Header в uint8_t*, а целое shared_ptr. Вы перезаписываете память в shared_ptr и, возможно, за ее пределами. shared_ptr затем пытается удалить себя, но вы сломали его.

Вы можете извлечь указатель объекта из shared_ptr с помощью метода get() (не забудьте проверить, не является ли он nullptr перед его использованием) .

  uint8_t* buff = (uint8_t*)output.get();
...