const char *循环期间更改值 [英] const char * changing value during loop
问题描述
我有一个函数,它通过 const char *
进行迭代,并使用字符将对象添加到 std :: map
如果它是系列的识别字符之一。
I have a function that iterates through a const char *
and uses the character to add objects to an instance of std::map
if it is one of series of recognized characters.
#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
的值不会再更改。
The character sequence passed is "++++++++++."
For the first three iterations, the print statements display the expected values of '+', '+', and '+', and the value of s
continues to be "+++++++++++.". However, on the fourth iteration, s
becomes mangled, producing bizarre values such as 'Ð'
, 'öê'
, 'cR '
, 'œk'
and many other character sequences. If the line that throws the exception is removed and the loop is allowed to continue, the value of s
does not change after again.
其他函数可以访问 s
,但是由于这不是一个多线程程序,我不明白为什么这么重要。我不是很困惑为什么 s
正在改变,但为什么它只在第四次迭代时改变。
Other functions have access to s
but since this is not a multithreaded program I don't see why that would matter. I am not so much confused about why s
is changing but why it only changes on the fourth iteration.
我已搜索SO,并且唯一相关的帖子是这一个,但它仍然不回答我的问题。 (研究一直很困难,因为搜索const char *改变值或类似的术语只是想出了上百个
I have searched SO and the only post that seems at all relevant is this one but it still doesn't answer my question. (Research has been difficult because searching "const char* changing value" or similar terms just comes up with hundreds of posts about what part of is is const).
最后,我知道我应该使用 std :: string
,如果没有答案,我会继续,但我仍然想理解这种行为。
Lastly, I know I should probably be using std::string
, which I will if no answers come forth, but I would still like to understand this behavior.
:
这是调用此函数的代码。
Here is the code that calls this function.
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();
}
c $ c> fname 是 ++++++++++。
展开,使每行有一个字符。
and the file fname
is ++++++++++.
spread such that there is one character per line.
编辑2:
以下是控制台输出的示例:
Here is an example of console output:
@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ß
推荐答案
您的加载
函数有缺陷。 c_str()
返回的 const char *
指针仅在基础 std: :string
对象存在。但 data
是 load
中的局部变量,并在返回后清除。它的缓冲区不会被零覆盖,而是保留为空闲内存。因此,在返回之后立即打印输出值很可能会工作,但您的程序可能会在那里输入新值,并且指针指向的值会改变。
Your load
function is flawed. The const char*
pointer returned by c_str()
is valid only until the underlying std::string
object exists. But data
is a local variable in load
and is cleared after return. Its buffer is not overwritten by zeroes but left as it were as free memory. Therefore printing out the value immediately after returning is likely to work but your program may put new values there and the value pointed by your pointer will change.
我建议使用 std :: string
作为负载的返回值,作为解决方法。
I suggest to use std::string
as the return value of load as a workaround.
这篇关于const char *循环期间更改值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!