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 гораздо удобнее для меня. И снова, я делаю все возможное, чтобы относиться к ним с величайшим уважением. Но этот конкретный проект имеет короткие периоды разработки с длинными участками сбора пыли, что не хорошо, когда смешивается с опасными методами кодирования. Живи и учись.