簡體   English   中英

在 C++ 中設置指向 null 的結構指針時,存儲的值消失

[英]Stored value disappears when setting a struct pointer to null in C++

我正在編寫一個 C++ 應用程序來對大型歌詞數據庫進行單詞搜索。 首先,我將每個單詞放入一個 Word 結構中,如下所示:

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

我有一個“makeNode”function,它執行以下操作:

  1. 接受每個單詞
  2. 創建一個新的 Word 結構並將單詞添加到其中
  3. 創建一個名為 node 的 Word* 指向新單詞
  4. 將指針存儲在 hash 表中。

在我的 makeNode function 中,我將 node->clean 設置為我的“干凈”字。 我可以通過 cout'ing node->clean 來打印這個詞。 但是當我將 node->same 設置為 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;

產生以下 output:

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: 

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

編輯:這是清潔 function。

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;
}

您需要將代碼簡化為顯示問題的最小示例,然后發布。

以下代碼無法顯示問題。 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;
}

Output 是:

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

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

clean不再存在時,該指針值不再有效,即 function 退出時。 它不再保證指向任何東西,所以你能按預期“再次”看到字符串是純粹的運氣。

我懷疑發生的情況是,memory曾經cleanse中的字符串clean的數據占用,已被重新用於結構word ,但不會立即被覆蓋。 碰巧的是,曾經保存第一個a的字節現在保存了結構的same成員的一部分。 因此,當您將 null 指針寫入node->same時,它具有將 0 字節寫入node->clean指向的位置的效果。 此后,它似乎指向一個空字符串。

好的,我們需要實際查看其中一些代碼才能確定,但這就是錯誤告訴您的內容:在某些時候,您正在分配的東西會覆蓋或刪除您的清理。 由於 y,ou 將其聲明為 char *,我猜您將其用作指向字符數組的指針,並且一個數組被別名為兩個不同單詞中的兩個“干凈”指針的可能性很大。

除了 new 和 cout 這也可能是 C。

其他一些讀物
C++中的struct和class有什么區別?
char * 與 std::string
從 C++ 中的 std::string 中刪除空格
降低 function 用於 C++ 字符串
如何否定 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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM