我正在编写一个应用程序,在该应用程序中我使用C++ STL中的Set类.我发现当我查询插入的最后一个元素时,对set-> find()的调用似乎总是失败.但是,如果我遍历集合,我能够看到我最初查询的元素.
为了试图弄清楚出了什么问题,我创建了一个示例应用程序,它展示了我所看到的相同行为.我的测试代码发布在下面.
对于实际的应用程序本身,我需要存储指向集合中对象的指针.这是导致奇怪行为的原因.或者是否有一个运算符我需要在类中重载我存储指针?
任何帮助,将不胜感激.
#include <stdio.h>
#include <set>
using namespace std;
#define MySet set<FileInfo *,bool(*)(const FileInfo *, const FileInfo*)>
class FileInfo
{
public:
FileInfo()
{
m_fileName = 0;
}
FileInfo( const FileInfo & file )
{
setFile( file.getFile() );
}
~FileInfo()
{
if( m_fileName )
{
delete m_fileName;
m_fileName = 0;
}
}
void setFile( const char * file )
{
if( m_fileName )
{
delete m_fileName;
}
m_fileName = new char[ strlen( file ) + 1 ];
strcpy( m_fileName, file );
}
const char * getFile() const
{
return m_fileName;
}
private:
char * m_fileName;
};
bool fileinfo_comparator( const FileInfo * f1, const FileInfo* f2 )
{
if( f1 && ! f2 ) return -1;
if( !f1 && f2 ) return 1;
if( !f1 && !f2 ) return 0;
return strcmp( f1->getFile(), f2->getFile() );
}
void find( MySet *s, FileInfo * value )
{
MySet::iterator iter = s->find( value );
if( iter != s->end() )
{
printf( "Found File[%s] at Item[%p]\n", (*iter)->getFile(), *iter );
}
else
{
printf( "No Item found for File[%s]\n", value->getFile() );
}
}
int main()
{
MySet *theSet = new MySet(fileinfo_comparator);
FileInfo * profile = new FileInfo();
FileInfo * shell = new FileInfo();
FileInfo * mail = new FileInfo();
profile->setFile( "/export/home/lm/profile" );
shell->setFile( "/export/home/lm/shell" );
mail->setFile( "/export/home/lm/mail" );
theSet->insert( profile );
theSet->insert( shell );
theSet->insert( mail );
find( theSet, profile );
FileInfo * newProfile = new FileInfo( *profile );
find( theSet, newProfile );
FileInfo * newMail = new FileInfo( *mail );
find( theSet, newMail );
printf( "\nDisplaying Contents of Set:\n" );
for( MySet::iterator iter = theSet->begin();
iter != theSet->end(); ++iter )
{
printf( "Item [%p] - File [%s]\n", *iter, (*iter)->getFile() );
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:
Found File[/export/home/lm/profile] at Item[2d458]
Found File[/export/home/lm/profile] at Item[2d458]
No Item found for File[/export/home/lm/mail]
Displaying Contents of Set:
Item [2d478] - File [/export/home/lm/mail]
Item [2d468] - File [/export/home/lm/shell]
Item [2d458] - File [/export/home/lm/profile]
Run Code Online (Sandbox Code Playgroud)
**编辑我有点难过,我必须添加这个.但正如我之前提到的,这是一个示例应用程序,它从较大的应用程序的不同部分提取,以显示我收到的故障.
它意味着在用堆分配的指针填充的集合上调用set :: find的单元测试.如果你对所有的new()都有问题,我会接受有关如何使用堆分配的指针神奇地填充集合而不使用它们的建议.否则评论"太多新的()调用"只会让你看起来很傻.
请关注正在发生的实际问题(现已解决).谢谢.
***编辑
也许我应该把这些放在原来的问题中.但是我希望有更多关注find()的问题(或者因为它结果是更像strcmp而不是更少的fileinfo_comparator函数),然后是复制粘贴PoC单元测试的代码审查.
以下是有关完整应用程序本身代码的一些要点.
Nik*_*sov 10
你的比较函数是错误的 - 它返回bool,而不是整数strcmp(3).return语句应该是这样的:
return strcmp( f1->getFile(), f2->getFile() ) < 0;
Run Code Online (Sandbox Code Playgroud)
看看这里.
另外,出于好奇,为什么不使用std::set<std::string>呢?STL实际上具有不错的默认值,并使您免于大量的手动内存管理.