在 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->same
写入空指针时,它具有将0 字节写入node->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 时存储的值消失的主要内容,如果未能解决你的问题,请参考以下文章