Visual C++ 2010 отображать / устанавливать итераторы несовместимы

Я вырываю свои волосы с этой ошибкой. Это функция поиска адресов в таблице символов для отладчика в эмуляторе 8080. Идея такова: у меня есть таблица символов с адресами и метками, и функция this берет адрес и пытается найти ближайший символ на заданном расстоянии (обычно 10). Затем он возвращает строку типа "метка" или "метка +2". Он возвращает NULL, если не находит совпадение достаточно близко.

Все работает как обычно, пока после того, как эмулируемый ЦП не выполнит переход, Visual C++ установит "несовместимость сопоставления / установки" в строке с циклом for. Я видел некоторые проблемы с многопоточностью, связанные с этим, и это многопоточное приложение, но карта символов используется только внутри одного потока и не затрагивается, кроме как для чтения, после того, как она была заполнена при запуске.

Я пробовал циклы while, для циклов, для каждого цикла, все с автоматическими итераторами или без них. Я попытался убрать возврат внутри цикла, сделать разрыв с установкой символа и расстояния, чтобы получить точные совпадения внизу за пределами цикла. Это все еще задыхается в той же самой точке. (Адрес 1418, но функция была вызвана шесть раз, и оба возвращали точное совпадение или NULL).

#define _CRT_SECURE_NO_WARNINGS

#include <string>
#include <stdio.h>
#include <string>
#include <map>

using namespace std;

map <int, string> symbol_list;

/* -- function that fills the table -- */

const char * look_up_symbol(int address, int max_distance){

  static char buffer[32];
  auto symbol = symbol_list.end();
  int distance; // distance to the current found symbol
  int c_distance; // current distance

  distance = 65536; // more than memory, bigger than big

  for (auto p = symbol_list.begin(); p != symbol_list.end(); ++p){
    if (address == p->first){
      // found an exact match
      strcpy(buffer, p->second.c_str());
      return buffer;
    }
    c_distance = abs(address - p->first);
    if (c_distance <= max_distance){
      // we've found one close enough to consider
      if (c_distance < distance){
        // closer then the closest one considered yet.
        symbol = p;
        distance = c_distance;
      }
    }
  }

  if (symbol  == symbol_list.end()){
    // we didn't find one close enough
    return NULL;
  }

  sprintf(buffer, "%s%+d", symbol->second.c_str(), distance);
  return buffer;

  return NULL;

}

Это действительно поставило меня в тупик... Я не уверен, как p не может соответствовать symbol_list.end(), так как это автоматический тип, и нет никакого кода, который действительно изменил бы содержимое symbol_list после его заполнения.

1 ответ

Оказывается, это было из-за опасности использования сырых строк. Я обычно очень хорошо держу их под контролем, но один вызов стека (в функции disasssembler), c-строка, которая принимает дизассемблированную инструкцию, была слишком маленькой. При первоначальном создании ему требовалось всего 9 байт плюс не более нуля (например, "SHLD 1F00"), и когда он сталкивался с более длинной инструкцией, это вызывало проблемы. Внутри этой функции 32 байта - это нормально, поскольку функция, которая читает их из файлов, захватывает только 23 байта, что больше, чем 21 байт, разрешенный для отображения на экране.

Я бы использовал std::string, но для некоторых вещей строки в стиле C гораздо удобнее для меня. И снова, я делаю все возможное, чтобы относиться к ним с величайшим уважением. Но этот конкретный проект имеет короткие периоды разработки с длинными участками сбора пыли, что не хорошо, когда смешивается с опасными методами кодирования. Живи и учись.

Другие вопросы по тегам