const char*在循环期间改变值

App*_*ish 1 c++ pointers const-char c-strings

我有一个迭代a的函数,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]]);
     }
 }
Run Code Online (Sandbox Code Playgroud)

传递的字符序列是"++++++++++." 前三次迭代,print语句显示'+','+'和'+'的预期值,值s继续为"+++++++++++++++++++++++++++++++++++++++++++++++++++ +." 然而,在第四次迭代,s变得错位,产生奇异值,例如'Ð','öê','cR ','œk'和许多其它的字符序列.如果删除抛出异常的行并允许循环继续,则值s不会再次更改.

其他函数可以访问,s但由于这不是一个多线程程序,我不明白为什么这很重要.我并不是为什么s要改变,而是为什么它只在第四次迭代中改变.

我搜索了SO,唯一看起来相关的帖子就是这个,但它仍然没有回答我的问题.(研究一直很困难,因为搜索"const char*change values"或类似的术语只会出现数百个关于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;
}
Run Code Online (Sandbox Code Playgroud)

在哪里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();
Run Code Online (Sandbox Code Playgroud)

}

该文件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ß
Run Code Online (Sandbox Code Playgroud)

Csq*_*Csq 7

你的load功能有缺陷.const char*返回的指针c_str()仅在基础std::string对象存在时才有效.但是data是一个局部变量load并且在返回后被清除.它的缓冲区不会被零覆盖,而是保留为空闲内存.因此,在返回后立即打印出值可能会起作用,但是程序可能会在那里放置新值,指针指向的值也会改变.

我建议使用std::stringload的返回值作为变通方法.