const char * изменение значения во время цикла

У меня есть функция, которая перебирает const char * и использует символ для добавления объектов в экземпляр std::map если это один из серии узнаваемых персонажей.

#define CHARSEQ const char*

void compile(CHARSEQ s) throw (BFCompilationError)
{
std::cout << "@Receive call " << s << std::endl;

for(int i = 0; s[i] != '\0'; i++)
{
if (std::string("<>-+.,[]").find_first_of(s[i]) == std::string::npos)
{
throw BFCompilationError("Unknown operator",*s,i);
}
std::cout << "@Compiling: " << s[i] << std::endl;
std::cout << "@address s " << (void*)s << std::endl;
std::cout << "@var s " << s << std::endl;
controlstack.top().push_back(opmap[s[i]]);
}
}

Переданная последовательность символов "++++++++++."
Для первых трех итераций операторы print отображают ожидаемые значения «+», «+» и «+», а также значение s продолжает быть «+++++++++++.» Однако на четвертой итерации s становится искаженным, производя странные ценности, такие как 'Ð', 'öê', 'cR ', 'œk' и многие другие последовательности символов. Если строка, которая выдает исключение, удаляется и цикл может продолжаться, значение s не меняется после снова.

Другие функции имеют доступ к s но поскольку это не многопоточная программа, я не понимаю, почему это имеет значение. Я не так сильно смущен, почему s меняется, но почему он меняется только на четвертой итерации.

Я искал ТАК, и единственный пост, который кажется вообще соответствующим этот но это все еще не отвечает на мой вопрос. (Исследование было трудным, потому что поиск «const char * change value» или подобных терминов просто приводит к сотням сообщения о том, что является частью const).

Наконец, я знаю, что, вероятно, я должен использовать std::stringЭто произойдет, если не будет ответов, но я все же хотел бы понять это поведение.

РЕДАКТИРОВАТЬ:

Вот код, который вызывает эту функцию.

CHARSEQ text = load(s);

std::cout << "@Receive load " << text << std::endl;

try
{
compile(text);
}
catch(BFCompilationError& err)
{
std::cerr << "\nError in bf code: caught BFCompilationError @" << err.getIndex() << " in file " << s << ":\n";
std::cerr << text << '\n';
for(int i = 0; i < err.getIndex(); i++)
{
std::cerr << " ";
}
std::cerr << "^\n";
std::cerr << err.what() << err.getProblemChar() << std::endl;
return 1;
}

куда load является:

CHARSEQ load(CHARSEQ fname)
{
std::ifstream infile (fname);
std::string data(""), line;
if (infile.is_open())
{
while(infile.good())
{
std::getline(infile,line);
std::cout << "@loading: "<< line << '\n';
data += line;
}
infile.close();
}
else
{
std::cerr << "Error: unable to open file: " << fname << std::endl;
}

return std::trim(data).c_str();

}

и файл fname является ++++++++++. Распространение так, что есть один символ на строку.

РЕДАКТИРОВАТЬ 2:

Вот пример вывода на консоль:

@loading: +
@loading: +
@loading: +
@loading: +
@loading: +
@loading: +
@loading: +
@loading: +
@loading: +
@loading: +
@loading: .
@Receive load ++++++++++.
@Receive call ++++++++++.
@Compiling: +
@address s 0x7513e4
@var s ++++++++++.
@Compiling: +
@address s 0x7513e4
@var s ++++++++++.
@Compiling: +
@address s 0x7513e4
@var s ++++++++++.
@Compiling:
@address s 0x7513e4
@var s ßu

Error in bf code: caught BFCompilationError @4 in file bf_src/Hello.txt:
ßu
^
Unknown operatorß

1

Решение

Ваш load функция несовершенна. const char* указатель возвращается c_str() действует только до std::string объект существует. Но data является локальной переменной в load и очищается после возвращения. Его буфер не перезаписывается нулями, а остается как свободная память. Поэтому распечатка значения сразу после возврата может сработать, но ваша программа может поместить туда новые значения, и значение, указанное указателем, изменится.

Я предлагаю использовать std::string в качестве возвращаемого значения нагрузки в качестве обходного пути.

7

Другие решения

Других решений пока нет …

А ты уже прошел курс программирования? Супер скидка!
Прокачать скилл $$$
×