2013-01-17 63 views
1

我有一個函數,它遍歷一個const char *,並使用該字符將對象添加到std::map的實例(如果它是一系列識別字符中的一個)。const char *在循環期間更改值

#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 *改變值」或類似術語只是出現了數百個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

我們需要看到調用這個函數的代碼。 –

+0

你還可以包含完整的控制檯輸出嗎?查看您正在討論的確切更改可能很有用。 –

回答

7

load功能是有缺陷的。由c_str()返回的const char*指針僅在基礎std::string對象存在之前有效。但dataload中的局部變量,並在返回後清零。其緩衝區不會被零覆蓋,而會保留爲空閒內存。因此,在返回後立即打印出值可能會起作用,但是您的程序可能會在此處添加新值,並且指針指向的值將會更改。

我建議使用std::string作爲負載的返回值作爲解決方法。