我正在编写一个C ++应用程序,用于在大型歌词数据库中进行单词搜索。首先,我将每个单词放入一个看起来像这样的Word结构中:
struct Word{
char* clean;
int size;
int position;
SongId id;
Word* same;
Word* diff;
};
我有一个“makeNode”函数执行以下操作:
在我的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;
}
答案 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);
}