2011-05-01 71 views
3

我正在編寫一個C++應用程序,以跨歌詞歌詞的大型數據庫進行單詞搜索。開始,我以每一個字,並把它變成一個字結構,看起來像這樣:在C++中將結構指針設置爲空時,存儲值消失

struct Word{ 
    char* clean; 
    int size; 
    int position; 
    SongId id; 
    Word* same; 
    Word* diff; 
}; 

我有一個「makeNode」功能,執行以下操作:

  1. 發生在每一個字
  2. 創建一個新的Word結構,並增加了字它
  3. 創建一個Word *稱爲節點指向新詞
  4. 存儲指針在哈希表。

在我的makeNode函數中,我將node-> clean設置爲我的「乾淨」字。我可以通過cout'ing node-> clean打印這個單詞。但是,當我將node->設置爲NULL時,我會丟失node-> clean。我不會失去節點 - >位置或節點 - >大小。如果我刪除了將node-> same分配給NULL的行,我不會丟失node-> clean。

char* clean = cleanse(word); 
Word* node = new Word; 
node->size = strlen(word); 
node->clean = clean; 
cout<<"MADE NODE FOR "<<node->clean<<endl; 
node->position = position; 
cout<<"4 node clean: "<<node->clean<<endl; 
node->id = id; 
cout<<"5 node clean: "<<node->clean<<endl; 
node->same = NULL; 
cout<<"6 node clean: "<<node->clean<<endl; 
cout<<"node position: "<<node->position<<endl; 
cout<<"node size: "<<node->size<<endl; 
node->diff = NULL; 

產生以下的輸出:

MADE NODE FOR again 
4 node clean: again 
5 node clean: again 
6 node clean: 
node position: 1739 
node size: 6 
0 node clean: 
1 node clean: 
3 node clean: 

誰能幫我把過去的這個錯誤?如果您需要更多信息,請告訴我。提前致謝!

編輯:這裏是清理功能。

char* SongSearch::cleanse(char* dirty) 
{ 

string clean; 
int iter = 0; 
while (!isalnum(dirty[iter])) 
{ 
    iter++; 
} 
while(dirty[iter]!='\0') 
{ 
    clean += dirty[iter]; 
    iter++; 
} 

int backiter = clean.length() - 1; 
while(!isalnum(clean[backiter])) 
{ 
    clean.erase(backiter, 1); 
    backiter--; 
} 


char c; 
    for (int i = 0; i<clean.length(); i++) 
{ 
    c = tolower(clean[i]); 
    clean[i] = c; 
} 

char* toReturn = (char*)(clean.c_str()); 
return toReturn; 
} 
+0

什麼是'cleanse'?一個函數?發佈其代碼。它返回本地char數組嗎? – Nawaz 2011-05-01 18:03:07

+0

如果你做某事的時候傷害了,不要這樣做。停止使用char *,Word *並使用std :: strings和Word的向量。並重新考慮你的struct的名字 - 爲什麼叫做Word? – 2011-05-01 18:08:38

回答

2

的問題是可能是在cleanse中,您將返回clean.c_str()

clean停止存在時(即函數退出時),該指針值停止有效。它不再保證指向任何東西,所以你真的很幸運,你會看到字符串「再次」按預期。

我懷疑的情況是,該使用的存儲器,可通過數據的字符串cleancleanse佔領,又被重新用於結構word,但不會立即覆蓋。恰巧,用於保存第一個a的字節現在持有您的結構的same成員的一部分。所以,當你寫一個空指針到node->same時,它的效果是寫一個0字節到node->clean指向的位置。此後,它似乎指向一個空字符串。

從新
0

好了,我們需要實際看到的代碼,其中的一些可以肯定的,但這裏的什麼錯誤是告訴你:在某些時候,你指定的東西,覆蓋或刪除您的清潔。既然你把它聲明爲一個char *,我猜你會用它作爲指向一個字符數組的指針,而且有可能一個數組被混淆爲兩個不同單詞中的兩個「乾淨」指針。

2

您需要將代碼縮減爲顯示問題的最小示例,然後發佈。

以下代碼無法顯示問題。的main和內容Word的定義是從你的代碼,在必要時獲得,然後我加入的代碼複製它來編譯:

#include <iostream> 
#include <cstring> 
using namespace std; 

typedef int SongId; 

struct Word{ 
    char* clean; 
    int size; 
    int position; 
    SongId id; 
    Word* same; 
    Word* diff; 
}; 

char *cleanse(const char *w) { 
    return (char *)w; 
} 
const char *word = "again "; 
const int position = 1739; 
const int id = 0; 

int main() { 
    char* clean = cleanse(word); 
    Word* node = new Word; 
    node->size = strlen(word); 
    node->clean = clean; 
    cout<<"MADE NODE FOR "<<node->clean<<endl; 
    node->position = position; 
    cout<<"4 node clean: "<<node->clean<<endl; 
    node->id = id; 
    cout<<"5 node clean: "<<node->clean<<endl; 
    node->same = NULL; 
    cout<<"6 node clean: "<<node->clean<<endl; 
    cout<<"node position: "<<node->position<<endl; 
    cout<<"node size: "<<node->size<<endl; 
    node->diff = NULL; 
} 

輸出是:

MADE NODE FOR again 
4 node clean: again 
5 node clean: again 
6 node clean: again 
node position: 1739 
node size: 6 
0

除了和cout這很可能會成爲C.

一些其他讀取
What are the differences between struct and class in C++?
char * Vs std::string
Remove spaces from std::string in C++
tolower function for C++ strings
How can I negate a functor in C++ (STL)?

嘗試使用以下的替代(未編譯樣品)

#include <iostream> 
#include <string> 
#include <algorithm> 
#include <functional> 

typedef int SongId; 

class Word{ 
    int position; 
    SongId id; 
    Word* same; 
    Word* diff; 

public: 
    const std::string word; 

    const int size() const { return clean.length() }; 

    Word(const std::string& word_, const int position_ = 1739, const int id_ = 0) 
    : clean(cleanse(word_)) 
    , position(position_) 
    , id(id_) 
    , same(NULL) 
    , diff(NULL) 
    { 
    cout<<"MADE NODE FOR "<< word_ << "\n" 
     <<"node clean: "<< word << "\n" 
     <<"node position: "<< position << "\n"; 
     <<"node size: "<< size() << endl; 
    } 

    static std::string cleanse(const std::string& dirty) 
    { 
    string clean(dirty); 

// Remove anything thats not alpha num 
    clean.erase(remove_if(clean.begin(), clean.end(), std::not1(::isalnum)), clean.end()); 
// make it lower case 
    std::transform(clean.begin(), clean.end(), clean.begin(), ::tolower); // or boost::to_lower(str); 

    return clean; 
    } 
}; 

const char *word = "again "; 

int main() { 
    Word* node = new Word(word); 
}