2013-04-30 61 views
0

我想調試一個與std :: string中包含的字符數組的範圍有關的問題。我已經發布了下面的相關代碼示例,從返回的std :: string的本地副本獲取C字符串

#include <iostream> 
#include <string> 

const char* objtype; 

namespace A 
{ 

std::string get_objtype() 
{ 
    std::string result; 
    std::string envstr(::getenv("CONFIG_STR")); 
    std::size_t pos1 = 0, pos2 = 0, pos3 = 0; 
    pos1 = envstr.find_first_of("objtype"); 
    if (pos1 != std::string::npos) 
    pos2 = envstr.find_first_of("=", pos1+7); 
    if (pos2 != std::string::npos) 
    { 
    pos3 = envstr.find_first_of(";", pos2+1); 
    if (pos3 != std::string::npos) 
     result = envstr.substr(pos2+1, pos3 - pos2 - 1); 
    } 
    const char* result_cstr = result.c_str(); 
    std::cerr << "get_objtype()" << reinterpret_cast<long>((void*)result_cstr) << std::endl; 
    return result; 
} 

void set_objtype() 
{ 
    objtype = get_objtype().c_str(); 
    std::cerr << "Objtype " << objtype << std::endl; 
    std::cerr << "main()" << reinterpret_cast<long>((void*)objtype) << std::endl; 
} 

} 

int main() 
{ 
    using namespace A; 
    std::cerr << "main()" << reinterpret_cast<long>((void*)objtype) << std::endl; 
    set_objtype(); 

    if (::strcmp(objtype, "AAAA") == 0) 
    std::cerr << "Do work for objtype == AAAA " << std::endl; 
    else 
    std::cerr << "Do work for objtype != AAAA" << std::endl; 
} 

這是用g ++ 4.2.1在MacOS 12.3上編譯和執行的。從運行,這是如下的輸出,

$ g++ -g -DNDEBUG -o A.exe A.cpp 
$ CONFIG_STR="objtype=AAAA;objid=21" ./A.exe 
main()0 
get_objtype()140210713147944 
Objtype AAAA 
main()140210713147944 
Do work for objtype == AAAA 
$ 

我的問題是這些: 從主印刷的指針值()和get_objtype()是相同的。這是由於RVO? 輸出的最後一行顯示即使當封閉的std :: string超出作用域時,指向C字符串的全局指針也可以。那麼,什麼時候返回的值超出範圍並且字符串數組被刪除?任何來自社區的幫助表示感謝。謝謝。

+0

get_objtype()中返回的字符串在語句後立即銷燬。即在擊中分號後。只是objtype指向的地址不會被任何其他數據覆蓋。因此你仍然看到價值「AAAA」。 – Jagannath 2013-04-30 04:31:16

+0

順便說一句,你想用這個例子達到什麼目的?除非你正在做一些不同的事情,否則讓代碼變得簡單易行。 – Jagannath 2013-04-30 04:33:07

+0

我想了解現有的一段代碼。 – 2013-04-30 04:35:06

回答

1

指針值不會改變,但它指向的內存可能不再是字符串的一部分。

objtype因爲get_objtype()的結果沒有保存在任何地方,因此在set_objtype()中將其設置爲無效,因此編譯器可以在那裏自由地殺死它。

它可能工作,但它訪問無效的內存,所以它是無效的代碼,如果你依賴於這樣的事情,你最終會遇到大問題。

+0

謝謝。那麼編譯器會在調用c_str()之前創建一個臨時字符串? – 2013-04-30 04:54:15

+0

直到在'objtype = get_objtype()。c_str();'get_方法返回一個實際字符串(在堆棧上)的分號之前,存在一個匿名字符串「existing」。 – John3136 2013-04-30 05:07:18

0

你應該看看使用objdump反彙編來檢查它的RVO。

但是,從我做過的實驗(使結果全局化並複製它),它看起來像c_str是引用計數。

相關問題