我编写了一组相当复杂的类来处理流(字符串、文件或内存)的迭代。这些不是标准流,也不相关。无论如何,由于遍历这些缓冲区并根据缓冲区执行操作,我希望能够在调试器中看到当前缓冲区位置。因此,仅出于调试原因,我将整个流复制到一个 vector ,并保存指向该 vector 中某个位置的指针。
下面的代码就像一个前向迭代器。我需要能够存储一个位置,然后使用它或更新它。请注意,此代码只是为了复制问题。
class foo
{
public:
foo ( std::string szTemp )
: nOffset( 0 )
{
vec.resize( szTemp.size() );
std::memcpy( &vec[ 0 ], szTemp.c_str(), szTemp.size() );
pChar = &vec[ 0 ];
}
foo( const foo & Other )
: vec( Other.vec )
, nOffset( Other.nOffset )
{
pChar = &vec[ nOffset ];
}
void Inc ( void )
{
++nOffset;
pChar = &vec[ nOffset ];
}
size_t nOffset;
char * pChar;
std::vector< char > vec;
};
int _tmain ( int argc, _TCHAR* argv[] )
{
foo a( "This is a temp string" );
a.Inc();
{
foo b = a;
b.Inc();
a = b;
} // Here is where the problem is seen
a.Inc();
}
问题,将b复制回a然后退出后,b.pChar的值变为非法。
据我了解,b 从 a 复制 vector ,然后 a 又从 b 复制回来。因为我在这个拷贝之后设置了 pChar 的值,所以它“应该”总是指向某个东西。但是,它的行为就像载体被破坏了。
这是怎么回事?
最佳答案
{
foo b = a;
b.Inc();
a = b;
} // Here is where the problem is seen
你的问题在这里。
a = b;
请求调用赋值运算符,您没有实现,因此,默认情况下将进行成员赋值。在此之后,您的 char pointer
将成为悬挂指针。以下代码将完成正确的工作。
class foo
{
public:
foo ( std::string szTemp )
: nOffset( 0 )
{
vec.resize( szTemp.size() );
std::memcpy( &vec[ 0 ], szTemp.c_str(), szTemp.size() );
pChar = &vec[ 0 ];
}
foo( const foo & Other )
: vec( Other.vec )
, nOffset( Other.nOffset )
{
pChar = &vec[ nOffset ];
}
foo& operator = (const foo& other)
{
foo tmp(other);
swap(tmp);
return *this;
}
void Inc ( void )
{
++nOffset;
pChar = &vec[ nOffset ];
}
void Swap(foo& other)
{
std::swap(vec, other.vec);
std::swap(nOffset, other.nOffset);
std::swap(pChar, other.pChar);
}
size_t nOffset;
char * pChar;
std::vector< char > vec;
};
关于c++ - std::vector 的异常行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17102840/