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

时间:2011-05-01 17:57:37

标签: c++ pointers hashtable cstring

我正在编写一个C ++应用程序,用于在大型歌词数据库中进行单词搜索。首先,我将每个单词放入一个看起来像这样的Word结构中:

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

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

  1. 接受每个单词
  2. 创建一个新的Word结构并将单词添加到其中
  3. 创建一个名为node *的节点,该节点指向新单词
  4. 将指针存储在哈希表中。
  5. 在我的makeNode函数中,我将node-> clean设置为我的“干净”字。我可以通过cout'ing node-> clean来打印这个单词。但是当我将node->设置为NULL时,我将丢失node-> clean。我不会丢失node-> position或node-> size。如果我删除我将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;
    }
    

4 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

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

clean不再存在时,指针值停止有效,即函数退出时。它不再保证指向任何东西,所以纯粹的运气是你曾经按照预期再次看到字符串。

我怀疑发生的事情是使用clean中的字符串cleanse的数据占用的内存已被重新用于结构{ {1}},但不会立即被覆盖。恰好,用于保存第一个word的字节现在成为结构的a成员的一部分。因此,当您向same写入空指针时,它会将{0}字节写入node->same所指向的位置。此后,它似乎指向一个空字符串。

答案 2 :(得分:0)

好的,我们需要确实看到其中一些代码确实存在,但这就是bug告诉你的内容:在某些时候,你会分配一些覆盖或删除你干净的内容。因为y,你将它声明为char *,我猜你用它作为指向一个字符数组的指针,并且很可能一个数组被别名化为两个不同单词中的两个“干净”指针。< / p>

答案 3 :(得分: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);
}