2014-07-18 60 views
1

對構造函數字符串(const char * s)有時會改變const char *中的字符的原因感到好奇。我有一個簡單的方法來檢查一個標誌是否被設置,以某種方式搜索一個樹並返回一個值來改變字符串。它似乎工作正常,如果我只使用字符串;然而,由於某些奇怪的原因,當我使用從另一個函數接收的const char *作爲函數的參數時,我接收到的const char *有時會返回不完整。這是我直到最近才找到的細微錯誤的原因。它似乎工作,如果在方法內我創建另一個字符串並將字符串參數追加到新字符串,但這似乎是解決此問題的錯誤方法。我相信這可能是對構造函數正確使用的誤解,有沒有人對這個微妙的問題有所瞭解?當用作參數時,字符串是否改變const char *

作爲一個簡單的例子,終端返回下面的結果,注意不完整字符的符號沒有正確複製,而是空白。

enter image description here

編輯:
@ T.C。
我絕不會責怪字符串類T.C.,我很清楚這是我的錯誤,我試圖理解這個問題。這很可能是對std :: string類中使用構造函數的誤解。一些背景故事我一起使用C/C++和Java進行練習。我創建了一個類,它似乎通過了C++中最小的測試,並創建了一個包裝器,以便我可以在C中使用它。當我傳遞一個字符串作爲參數而不是const char *時,它可以毫無問題地工作;不過就我的理解來說,std :: string應該複製這些字符,儘管這我不確定。我意識到,一個人會告訴我只使用C++,而不是混合兩個人在其他問題的答案,如果個人混合兩者,但任何方向將不勝感激。

我想將問題縮短爲原來的時間,但在添加代碼之前發佈。附件是其使用的一小部分,以及我之前找不到的缺少字符的正確圖片。

LZW.c(C類)

... 
const char * tex = Trie_Int_longestPrefix(trie,input); //Find max prefix match tex 
printf("%25s\t",tex); 
//FOR SOME REASON TEX CHANGES AFTER THIS CALL 
arr[size++] = Trie_Int_get(trie,tex); //Add encoding 
printf("%25s\n",tex); 
int t = strlen(tex); 
... 

ctrie.cpp(C-包裝類)

... 
//Return Value 
int Trie_Int_get(Trie_Int * t,const char * key){return ((Trie<int> *)t)->get(key); } 
... 
//Find and return longest prefix of s in TST 
const char * Trie_Int_longestPrefix(Trie_Int * t,const char * s){return ((Trie<int> *)t)->longestPrefix(s).c_str();} 
... 

Trie.ii(C++類)

... 
template<typename value> 
value Trie<value>::get(std::string key,const bool & ignoreCase) const { 
    if(key.empty()){throw std::invalid_argument("key must have length >= 1");} 
    if(ignoreCase)__toLowerCase(key); 
    TrieNode* x = get(root,key,0,ignoreCase); 
    return x!=nullptr? x->val : defVal; 
} 
template<typename value> 
std::string Trie<value>::longestPrefix(std::string key,const bool & ignoreCase) const{ 
...Kind of Long 
} 
... 
+5

可能與'string'無關,並且與代碼的其他部分無關。 –

+4

請張貼展示問題的代碼。 –

+1

您的代碼中存在一個錯誤。如果您想幫助識別錯誤,您必須發佈一個小型自包含示例來重現問題。 –

回答

4
template<typename value> 
std::string Trie<value>::longestPrefix(
    std::string key,const bool & ignoreCase) const; 

//Find and return longest prefix of s in TST 
const char * Trie_Int_longestPrefix(Trie_Int * t,const char * s) 
{return ((Trie<int> *)t)->longestPrefix(s).c_str();} 

當一個函數返回一個類類型(直接,不是對類型的引用)時,calli該函數創建一個臨時類對象,該對象直到調用它的全表達式的末尾。 (最常見的一種「全表達」的是,像在這種情況下,一個語句。)

std::string::c_str()返回其保證有效,直到string的任何非const構件被稱爲C字符串的指針,包括析構函數。

因此Trie_Int_longestPrefix函數返回一個已經無效的指針,並且它的任何用法都算作未定義的行爲。

在您的測試運行中,指向無效指針的內存恰好在第一次打印時仍含有一些「預期」數據。但是第二次,其他一些代碼顯然已經重用了其他內存區域。

+0

啊我明白了,謝謝。我最初很困惑,爲什麼c_str()在我離開方法後一直工作;所以最初嘗試使用一個結構,但恢復到簡單地爲它分配空間後,我解決了另一個問題,決定兩個方法似乎有點混亂,因爲我檢查值時我從來沒有看到差異,我認爲它是好的。我想我會簡單地分配內存,並記住在函數外部刪除它。 – kdgwill

相關問題