C++ Visual Studio 2005中使用字符串::迭代器时出现空指针问题

C++ Visual Studio 2005中使用字符串::迭代器时出现空指针问题,c++,string,visual-studio-2005,iterator,C++,String,Visual Studio 2005,Iterator,我正在使用一些遗留代码。在以下场景中,遗留代码在生产模式下工作。我正在尝试为测试目的构建遗留代码的命令行版本。我怀疑这里有一个环境设置问题,但是我对C++和VisualStudio(长时间Eclipse /java家伙)比较新。 此代码试图从流中读入字符串。它读入一个简短的文本,在我的调试场景中,该文本的值为11。然后,它应该读11个字符。但这段代码在第一个字符上就失效了。具体来说,在下面的read方法中,ptr为null,因此fread调用引发异常。为什么ptrNULL 需要澄清的是,ptr在

我正在使用一些遗留代码。在以下场景中,遗留代码在生产模式下工作。我正在尝试为测试目的构建遗留代码的命令行版本。我怀疑这里有一个环境设置问题,但是我对C++和VisualStudio(长时间Eclipse /java家伙)比较新。 此代码试图从流中读入字符串。它读入一个简短的文本,在我的调试场景中,该文本的值为11。然后,它应该读11个字符。但这段代码在第一个字符上就失效了。具体来说,在下面的
read
方法中,
ptr
为null,因此
fread
调用引发异常。为什么
ptr
NULL

需要澄清的是,
ptr
在操作符>>(字符串)和操作符>>(字符)调用之间变为空

这里是阅读短文的方法,并查看文件缓冲区等。看起来它工作正常

Mystream& Mystream::operator>>(short& n )
{
    read( ( char* )&n, sizeof( n ) );
    SwapBytes( *this, ( char* )&n, sizeof( n ) );
    return *this;
}
现在,读取字符的方法如下:

Mystream& Mystream::operator>>(char& n )
{
    read( ( char* )&n, sizeof( n ) );
    return *this;
}
读取方法为:

Mystream& Mystream::read( char* ptr, int n )
{
fread( (void*)ptr, (size_t)1, (size_t)n, fp );
return *this;
} 
有一件事我不明白,在字符串输入法中,*它是一个字符,对吗?那么,为什么操作符>>(char&n)方法在该行上被调度?在调试器中,它看起来像*it是一个0(尽管一位同事告诉我他在这方面不信任2005调试器),因此,它看起来像&n被视为空指针,因此read方法抛出异常

你能提供的任何见解都会非常有用

谢谢 约翰

另外,出于好奇,
Swap
字节看起来如下:

inline void SwapBytes( Mystream& bfs, char * ptr, int nbyte, int nelem = 1)
{ 
    // do we need to swap bytes?
if( bfs.byteOrder() != SYSBYTEORDER )
    DoSwapBytesReally( bfs, ptr, nbyte, nelem );
}
MyStream::operator>>(string &s) { 
    short size;

    fread((void *)&size, sizeof(size), 1, fP);
    size = ntohs(size); // oops: after reading edited question, this is really wrong.
    s.resize(size);
    fread((void *)&s[0], 1, size, fp);
    return *this;
}
doswapbytes实际上看起来像:

void DoSwapBytesReally( Mystream& bfs, char * ptr, int nbyte, int nelem )
{
    // if the byte order of the file
    // does not match the system byte order
    // then the bytes should be swapped
int i, n;
char temp;

#ifndef _DOSPOINTERS_
char *ptr1, *ptr2;
#else _DOSPOINTERS_
char huge *ptr1, huge *ptr2;
#endif _DOSPOINTERS_

int nbyte2;

nbyte2 = nbyte/2;

for ( n = 0; n < nelem; n++ ) 
{
    ptr1 = ptr;
    ptr2 = ptr1 + nbyte - 1;

    for ( i = 0; i < nbyte2; i++ ) 
    {
        temp = *ptr1;
        *ptr1++ = *ptr2;
        *ptr2-- = temp;
    }

    ptr += nbyte;
}
}
void doswapbytes实际(Mystream&bfs,char*ptr,int nbyte,int nelem)
{
//如果文件的字节顺序
//与系统字节顺序不匹配
//然后应该交换字节
inti,n;
焦炭温度;
#ifndef\u剂量指示器_
字符*ptr1,*ptr2;
#否则!_
字符巨*ptr1,巨*ptr2;
#endif\u剂量指针_
int-nbyte2;
nbyte2=nbyte/2;
对于(n=0;n
我要扔掉这堆乱七八糟的东西,重新开始。从代码推断,如果您实际工作过,则大致相当于以下内容:

inline void SwapBytes( Mystream& bfs, char * ptr, int nbyte, int nelem = 1)
{ 
    // do we need to swap bytes?
if( bfs.byteOrder() != SYSBYTEORDER )
    DoSwapBytesReally( bfs, ptr, nbyte, nelem );
}
MyStream::operator>>(string &s) { 
    short size;

    fread((void *)&size, sizeof(size), 1, fP);
    size = ntohs(size); // oops: after reading edited question, this is really wrong.
    s.resize(size);
    fread((void *)&s[0], 1, size, fp);
    return *this;
}

在这种情况下,将大部分工作委托给其他职能部门似乎没有多大收获——这会更直接地完成工作,但仍然没有比原来的工作更长或更复杂(如果有的话,我会说相反)。

我发现公司里有一个灰胡子,可以解释我的情况。(我已经和两位老前辈谈过了,所以我想我已经涵盖了老前辈的攻击途径。)上面的代码不是符合ANSI标准的STL代码。在VisualStudio2005中,Microsoft首次引入STL,但出现了一些问题。尤其是以前工作的旧代码现在在2005年会失败(我认为64位模式可能也会在其中起作用。)因此,代码将无法在调试模式下工作(但它将在发布模式下工作)。这里有一篇局部文章。

我看到的特定问题与问题的第一个方法中的行:
it=str.begin()
有关
str
是一个空字符串。因此,
str.begin()
在技术上没有定义。VisualStudio在调试模式和发布模式之间对这种情况的处理方式不同。(无法在调试中执行此操作,您可以在发行版中执行。)


总之,灰胡子暗示重写正是杰瑞的。具有讽刺意味的是,灰胡子已经在几个文件中修复了这个问题,但却忽略了将其检查到主线中。哦。这吓坏了&#$!!我不懂。

Where方法读起来很短吗?您似乎认为“char&n”语法与指针有某种关联。事实并非如此。它声明了一个引用。它被绑定到一个“char”对象“*It”,这是它应该做的。阅读有关你最喜欢的C++书籍中的引用。我的见解是:扔掉它并从头开始可能比尝试修复这样一个混乱更容易。“安德斯”调试器验证它不是空的。读取函数中的ptr为空。@AndreyT良好。是的,这是有道理的,但是我不理解为什么在这个上下文中read中的ptr值为null。是吗?
&s[0]
在字符串长度为零时无效。@约翰:是的,这是假设所有序列化的字符串长度均为非零。当然,我们还不知道这是不是真的——事实上,从代码来看,我猜那些知道的人几年前就忘记了(DOS指针?真的?!)不要说DOS人的坏话:)我是他们中的一员8-@AndersK:我不是说他们的坏话,只是指出代码显然很古老,而且似乎至少有几十年的“技术债务”。在我们公司,我们称之为“传统代码”,显然它有一个更好的环