我有一个迭代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
为什么会发生变化感到困惑,但为什么它只会在第四次迭代时发生变化。
我搜索了SO,唯一似乎相关的帖子是this one,但它仍然没有回答我的问题。 (研究很困难,因为搜索“const char * change values”或类似术语只会出现数百posts about what part of is is 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ß
答案 0 :(得分:7)
您的load
功能存在缺陷。 const char*
返回的c_str()
指针仅在基础std::string
对象存在之前有效。但是data
是load
中的局部变量,并在返回后被清除。它的缓冲区不会被零覆盖,而是保留为空闲内存。因此,在返回后立即打印出值可能会起作用,但是程序可能会在那里放置新值,指针指向的值也会改变。
我建议使用std::string
作为加载的返回值作为解决方法。