在 C++ 中将结构指针设置为 null 时存储的值消失

Posted

技术标签:

【中文标题】在 C++ 中将结构指针设置为 null 时存储的值消失【英文标题】:Stored value disappears when setting a struct pointer to null in C++ 【发布时间】:2011-08-16 13:18:39 【问题描述】:

我正在编写一个 C++ 应用程序来在大型歌词数据库中进行单词搜索。首先,我将每个单词放入一个 Word 结构中,如下所示:

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

我有一个“makeNode”函数,它执行以下操作:

    接受每个单词 创建一个新的 Word 结构并将单词添加到其中 创建一个 Word* 名为 node 的指向新单词的节点 将指针存储在哈希表中。

在我的 makeNode 函数中,我将 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;

产生以下输出:

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;

【问题讨论】:

什么是cleanse?一个函数?贴出它的代码。它是否返回本地字符数组? 如果你在做某事时感到疼痛,那就不要去做。停止使用 char *、Word * 并使用 std::strings 和 Word 的向量。重新考虑一下你的结构的名字——为什么叫 Word???? 【参考方案1】:

好的,我们需要实际查看其中一些代码才能确定,但​​这是错误告诉您的内容:在某些时候,您分配的内容会覆盖或删除您的 clean。由于 y,ou 将其声明为 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

【讨论】:

【参考方案3】:

问题可能是在cleanse,你返回clean.c_str()

clean 不再存在时,该指针值不再有效,也就是函数退出的时候。它不再保证指向任何东西,所以你能按预期“再次”看到字符串是纯粹的运气。

我怀疑发生的情况是,用于的内存被cleanse中的字符串clean的数据占用,已被重新用于结构word,但是不会立即被覆盖。碰巧的是,曾经保存第一个a 的字节现在保存了结构的same 成员的一部分。因此,当您向node-&gt;same 写入空指针时,它具有将0 字节写入node-&gt;clean 指向的位置的效果。此后,它似乎指向一个空字符串。

【讨论】:

【参考方案4】:

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

其他一些阅读What are the differences between struct and class in C++?char * Vs std::stringRemove spaces from std::string in C++tolower function for C++ stringsHow 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);

【讨论】:

以上是关于在 C++ 中将结构指针设置为 null 时存储的值消失的主要内容,如果未能解决你的问题,请参考以下文章

在Golang中将结构指针转换为接口指针

在 C++ 向量中存储指针时出错

如何在 C++ 中将指针转换/转换为引用

在 C++ 中将指针转换为数组形式的问题?

在 C++ 中将静态数组声明为指针

C语言 NULL赋结构体指针变量