【问题标题】:const char * changing value during loopconst char * 在循环期间改变值
【发布时间】:2013-01-17 22:44:45
【问题描述】:

我有一个函数,它遍历 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]]);
     }
 }

传递的字符序列是"++++++++++." 对于前三个迭代,打印语句显示 '+'、'+' 和 '+' 的预期值,s 的值继续为 "+++++++++++. ”。然而,在第四次迭代中,s 被破坏,产生诸如'Ð''öê''cR ''œk' 和许多其他字符序列之类的奇怪值。如果抛出异常的行被删除,允许循环继续,s 的值不会再次改变。

其他函数可以访问s,但由于这不是一个多线程程序,我不明白这有什么关系。我对为什么s 会发生变化而不是为什么它只在第四次迭代时发生变化感到困惑。

我已经搜索过 SO,唯一看起来完全相关的帖子是 this one,但它仍然没有回答我的问题。 (研究一直很困难,因为搜索“const char* changed value”或类似的术语只会出现数百个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ß

【问题讨论】:

  • 我们需要看看调用这个函数的代码。
  • 能否也包含完整的控制台输出?查看您正在谈论的确切更改可能会很有用。

标签: c++ pointers c-strings const-char


【解决方案1】:

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

我建议使用std::string 作为 load 的返回值作为解决方法。

【讨论】:

    猜你喜欢
    • 2014-03-28
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 2011-01-04
    • 2013-04-23
    相关资源
    最近更新 更多