在 C++ 中将结构指针设置为 null 时,存储的值消失
我正在编写一个 C++ 应用程序来在大型歌词数据库中进行单词搜索。首先,我将每个单词放入一个 Word 结构中,如下所示:
struct Word{
char* clean;
int size;
int position;
SongId id;
Word* same;
Word* diff;
};
我有一个“makeNode”函数,它执行以下操作:
- 接受每个单词
- 创建一个新的 Word 结构并将该单词添加到其中
- 创建一个Word* 称为指向新单词的节点,
- 将指针存储在哈希表中。
在我的 makeNode 函数中,我将 node->clean 设置为我的“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;
}
I'm writing a C++ application to do a word search across a large database of song lyrics. to start, I'm taking each word and putting it into a Word struct that looks like this:
struct Word{
char* clean;
int size;
int position;
SongId id;
Word* same;
Word* diff;
};
I have a "makeNode" function that does the following:
- takes in each word
- creates a new Word struct and adds the word to it
- creates a Word* called node which points to the new word
- stores the pointer in a hash table.
In my makeNode function, I set node->clean to my "clean" word. I can print the word by cout'ing node->clean. But when I set node->same to NULL, I lose node->clean. I don't lose node->position or node->size. If I remove the line where I assign node->same to to NULL, I do not lose 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;
yields the following 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:
Can anyone help me get past this error? If you need more info, let me know. Thanks in advance!
EDIT: here is the cleanse 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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题可能是在
cleanse
中,您返回clean.c_str()
。当 clean 不再存在(即函数退出时)时,该指针值将不再有效。它不再保证指向任何东西,因此您能够按预期“再次”看到该字符串纯属运气。
我怀疑发生的情况是
cleanse
中的字符串clean
的数据占用的内存已被重新用于结构word
,但不会立即被覆盖。碰巧的是,用于保存第一个a
的字节现在保存了结构体的same
成员的一部分。因此,当您向node->same
写入空指针时,它的效果是向node->clean
指向的位置写入 0 字节。此后,它似乎指向一个空字符串。The problem is probably that in
cleanse
, you returnclean.c_str()
.That pointer value ceases to be valid when
clean
ceases to exist, which is when the function exits. It is no longer guaranteed to point to anything, so it's pure luck that you're ever seeing the string "again" as expected.What I suspect happens is that the memory that used to be occupied by the data for the string
clean
incleanse
, has been re-used for the structureword
, but is not immediately overwritten. It just so happens that the byte that used to hold the firsta
now holds part of thesame
member of your struct. So, when you write a null pointer tonode->same
, it has the effect of writing a 0 byte to the location pointed to bynode->clean
. Thereafter, it appears to point to an empty string.您需要将代码减少到显示问题的最小示例,然后发布该示例。
以下代码无法显示问题。
main
的内容和Word
的定义是从您的代码中复制的,然后我根据需要添加了代码以使其编译:输出为:
You need to reduce your code to a minimal example which displays the problem, and post that.
The following code fails to display the problem. The contents of
main
and the definition ofWord
are copied from your code, then I have added code as necessary to get it to compile:Output is:
好吧,我们需要实际查看其中一些代码才能确定,但这就是错误告诉您的内容:在某些时候,您正在分配一些会覆盖或删除您的清理的东西。由于您将其声明为 char *,我猜您将其用作指向字符数组的指针,并且一个数组很可能被别名为两个不同单词中的两个“干净”指针。
Okay, we'd need to actually see the code for some of these to be sure, but here's what the bug is telling you: at some point, you're assigning to something that overwrites or deletes your clean. Since y,ou declare it as a char *, I'm guessing you use it as a pointer to an array of characters, and the odds are good that one array is being aliased to two "clean" pointers in two different Words.
除了 new 和 cout 之外,这也可能是 C。
其他一些阅读
C++ 中的结构体和类有什么区别?< /a>
char * 与 std::string< br>
在 C++ 中从 std::string 中删除空格
C++ 字符串的 tolower 函数
如何对 C++ (STL) 中的函子取反?
尝试以下替代方案(未编译的示例)
Aside from new and cout this might as well be C.
Some other reading
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)?
Try the following alternative (uncompiled sample)