用于编码目的的用户定义的IO streambuf问题 [英] Problem with user-defined IO streambuf for encoding purposes

查看:40
本文介绍了用于编码目的的用户定义的IO streambuf问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我在使用以下代码时遇到了一些困难。我已将

剥离它至少是为了证明手头的问题。


编译器:MS Visual C ++ 2005 Express Edition(出现类似问题)

with 2008)


运行时库:所有多线程变体都被视为失败

[DLL / Static] | [Debug | Release]


目的:定义一个用户定义的流缓冲区,处理每个

的传入字符并将其转换为编码值。将

编码字符放入本地缓冲区以进行输出。最简单的情况

将是一个将每个字符转换为大写的编码器。一个更复杂的情况是编码器将纯文本编码为

base64编码(这不是一对一的字符编码,它是3

字符到4字符编码,这就是为什么内部缓冲区需要



问题:代码抛出一个

hsl_d.exe中的未处理异常:0xC0000005:访问冲突读取位置0x00000000。"

在encoderbuf :: underflow c = 51之后字符''3'已被读取。

这基本上告诉我,在IO

库的内部深处,某些东西被解除引用而未被分配。


问题:

1)其他编译器是否会出现这种情况? (需要测试)

2)这是IO库的问题吗? (我不太可能认为)

3)我做了些蠢事吗? (更有可能)如果是这样的话?


参考文献:

C ++标准库 - 教程和参考(13.13.3用户定义的
Stream Buffers)

代码:


#include< iostream>

#include< sstream>


class encoderbuf:public std :: streambuf {


char mCharBuf [128];

int mBufLen;

int mBufPos;

public:

// ------------------- -------------------------------------------

/ **默认构造函数* /

encoderbuf()

:std :: streambuf()

,mBufLen(0)

,mBufPos(0)

{

}


// -------- -------------------------------------------------- ----

/ **传出数据* /

虚拟int_type下溢(){

int_type c = EOF;

if(mBufPos< mBufLen){

c = mCharBuf [mBufPos ++];

}

std :: cout<< ; " encoderbuf :: underflow c =" << c<< std :: endl;


返回c;

}


// ------- -------------------------------------------------- -----

/ **传入数据* /

虚拟int_type溢出(int_type c){

std :: cout< < encoderbuf :: overflow c =" << c<< std :: endl;

// TODO:在这里做编码

mCharBuf [mBufLen ++] = c;

返回c;

}

};


// --------------------- -----------------------------------------

int main(int argc,char ** argv){

encoderbuf buf;

std :: iostream iostr(& buf);

iostr << 12345<< std :: endl;

std :: stringstream sstr;

iostr> sstr.rdbuf(); //处理字符'3'的例外情况

std :: string str = sstr.str();

std :: cout<< ; main str = << str<< std :: endl;

}

输出:

encoderbuf :: overflow c = 49

encoderbuf ::溢出c = 50

encoderbuf :: overflow c = 51

encoderbuf :: overflow c = 52

encoderbuf :: overflow c = 53

encoderbuf :: overflow c = 10

encoderbuf :: underflow c = 49

encoderbuf :: underflow c = 50

encoderbuf :: underflow c = 51

popup:hsl_d.exe中0x00529bcc处的未处理异常:0xC0000005:

访问冲突读取位置0x00000000。

Hi everyone,

I''m having some difficulty with the following piece of code. I have
stripped it to it''s bare minimum to demonstrate the problem at hand.

Compiler: MS Visual C++ 2005 Express Edition (similar problem arises
with 2008)

Runtime Library: All multi-threaded variants have been seen to fail
[DLL/Static] | [Debug|Release]

Purpose: define a user defined stream buffer that processes each
incoming character and translates it to an encoded value. Place the
encoded character into a local buffer for output. The most simple case
would be an encoder that translates each character to upper case. A
more complicated case would be an encoder that encodes plain-text to
base64 encoding (this is not a one-to-one character encoding, it''s a 3
character to 4character encoding, this is why an internal buffer is
needed)

Problem: The code throws an "Unhandled exception at 0x00529bcc in
hsl_d.exe: 0xC0000005: Access violation reading location 0x00000000."
after the "encoderbuf::underflow c = 51" character ''3'' has been read.
This basically tells me that deep down in the internals of the IO
library something is being dereferenced that is not allocated.

Question(s):
1) Does this occur with other compilers? (requires testing)
2) Is this a problem with the IO library? (unlikely I think)
3) Am I doing something stupid? (more than likely) And if so what?

References:
C++ Standard Library - A Tutorial and Reference (13.13.3 User-Defined
Stream Buffers)
Code:

#include <iostream>
#include <sstream>

class encoderbuf : public std::streambuf {

char mCharBuf[128];
int mBufLen;
int mBufPos;
public:
//--------------------------------------------------------------
/** default constructor */
encoderbuf()
: std::streambuf()
, mBufLen(0)
, mBufPos(0)
{
}

//--------------------------------------------------------------
/** outgoing data */
virtual int_type underflow () {
int_type c = EOF;
if (mBufPos < mBufLen) {
c = mCharBuf[mBufPos++];
}
std::cout << "encoderbuf::underflow c = " << c << std::endl;

return c;
}

//--------------------------------------------------------------
/** incoming data */
virtual int_type overflow (int_type c) {
std::cout << "encoderbuf::overflow c = " << c << std::endl;
//TODO: do encoding here
mCharBuf[mBufLen++] = c;
return c;
}
};

//--------------------------------------------------------------
int main (int argc, char ** argv) {
encoderbuf buf;
std::iostream iostr(&buf);
iostr << 12345 << std::endl;
std::stringstream sstr;
iostr >sstr.rdbuf(); // EXCEPTION AT PROCESSING CHARACTER ''3''

std::string str = sstr.str();
std::cout << "main str = " << str << std::endl;
}
Output:
encoderbuf::overflow c = 49
encoderbuf::overflow c = 50
encoderbuf::overflow c = 51
encoderbuf::overflow c = 52
encoderbuf::overflow c = 53
encoderbuf::overflow c = 10
encoderbuf::underflow c = 49
encoderbuf::underflow c = 50
encoderbuf::underflow c = 51
popup: Unhandled exception at 0x00529bcc in hsl_d.exe: 0xC0000005:
Access violation reading location 0x00000000.

推荐答案

hs********@gmail.com 写道:

大家好,


我对以下代码有些困难。我已将

剥离它至少是为了证明手头的问题。


编译器:MS Visual C ++ 2005 Express Edition(出现类似问题)

with 2008)


运行时库:所有多线程变体都被视为失败

[DLL / Static] | [Debug | Release]


目的:定义一个用户定义的流缓冲区,处理每个

的传入字符并将其转换为编码值。将

编码字符放入本地缓冲区以进行输出。最简单的情况

将是一个将每个字符转换为大写的编码器。一个更复杂的情况是编码器将纯文本编码为

base64编码(这不是一对一的字符编码,它是3

字符到4字符编码,这就是为什么内部缓冲区需要



问题:代码抛出一个

hsl_d.exe中的未处理异常:0xC0000005:访问冲突读取位置0x00000000。"

在encoderbuf :: underflow c = 51之后字符''3'已被读取。

这基本上告诉我,在IO

库的内部深处,某些东西被解除引用而未被分配。


问题:

1)其他编译器是否会出现这种情况? (需要测试)

2)这是IO库的问题吗? (我不太可能认为)

3)我做了些蠢事吗? (更有可能)如果是这样的话?


参考文献:

C ++标准库 - 教程和参考(13.13.3用户定义的
Stream Buffers)


代码:


#include< iostream>

#include < sstream>


class encoderbuf:public std :: streambuf {


char mCharBuf [128];

int mBufLen;

int mBufPos;

public:

// --------------- -----------------------------------------------

/ **默认构造函数* /

encoderbuf()

:std :: streambuf()

,mBufLen(0 )

,mBufPos(0)

{

}


// ---- -------------------------------------------------- --------

/ **传出数据* /

虚拟int_type下溢(){

int_type c = EOF;

if(mBufPos< mBufLen){

c = mCharBuf [mBufPos ++];

}

std :: cout<< " encoderbuf :: underflow c =" << c<< std :: endl;


返回c;

}


// ------- -------------------------------------------------- -----

/ **传入数据* /

虚拟int_type溢出(int_type c){

std :: cout< < encoderbuf :: overflow c =" << c<< std :: endl;

// TODO:在这里做编码

mCharBuf [mBufLen ++] = c;
Hi everyone,

I''m having some difficulty with the following piece of code. I have
stripped it to it''s bare minimum to demonstrate the problem at hand.

Compiler: MS Visual C++ 2005 Express Edition (similar problem arises
with 2008)

Runtime Library: All multi-threaded variants have been seen to fail
[DLL/Static] | [Debug|Release]

Purpose: define a user defined stream buffer that processes each
incoming character and translates it to an encoded value. Place the
encoded character into a local buffer for output. The most simple case
would be an encoder that translates each character to upper case. A
more complicated case would be an encoder that encodes plain-text to
base64 encoding (this is not a one-to-one character encoding, it''s a 3
character to 4character encoding, this is why an internal buffer is
needed)

Problem: The code throws an "Unhandled exception at 0x00529bcc in
hsl_d.exe: 0xC0000005: Access violation reading location 0x00000000."
after the "encoderbuf::underflow c = 51" character ''3'' has been read.
This basically tells me that deep down in the internals of the IO
library something is being dereferenced that is not allocated.

Question(s):
1) Does this occur with other compilers? (requires testing)
2) Is this a problem with the IO library? (unlikely I think)
3) Am I doing something stupid? (more than likely) And if so what?

References:
C++ Standard Library - A Tutorial and Reference (13.13.3 User-Defined
Stream Buffers)
Code:

#include <iostream>
#include <sstream>

class encoderbuf : public std::streambuf {

char mCharBuf[128];
int mBufLen;
int mBufPos;
public:
//--------------------------------------------------------------
/** default constructor */
encoderbuf()
: std::streambuf()
, mBufLen(0)
, mBufPos(0)
{
}

//--------------------------------------------------------------
/** outgoing data */
virtual int_type underflow () {
int_type c = EOF;
if (mBufPos < mBufLen) {
c = mCharBuf[mBufPos++];
}
std::cout << "encoderbuf::underflow c = " << c << std::endl;

return c;
}

//--------------------------------------------------------------
/** incoming data */
virtual int_type overflow (int_type c) {
std::cout << "encoderbuf::overflow c = " << c << std::endl;
//TODO: do encoding here
mCharBuf[mBufLen++] = c;



很可能你的意思是

mCharBuf [mBufPos ++] = c;

这里。 mBufPos,而不是mBufLen。

Most likely you meant
mCharBuf[mBufPos++] = c;
here. mBufPos, not mBufLen.


返回c;

}

};


// ------------------------------------------- -------------------

int main(int argc,char ** argv){

encoderbuf buf;

std :: iostream iostr(& buf);

iostr<< 12345<< std :: endl;

std :: stringstream sstr;

iostr> sstr.rdbuf(); //处理字符'3'的例外情况

std :: string str = sstr.str();

std :: cout<< ; main str = << str<< std :: endl;

}


输出:

encoderbuf :: overflow c = 49

encoderbuf :: overflow c = 50

encoderbuf :: overflow c = 51

encoderbuf :: overflow c = 52

encoderbuf :: overflow c = 53

encoderbuf :: overflow c = 10

encoderbuf :: underflow c = 49

encoderbuf :: underflow c = 50

encoderbuf :: underflow c = 51

popup:hsl_d.exe中0x00529bcc处的未处理异常:0xC0000005:

访问冲突读取位置0x00000000。
return c;
}
};

//--------------------------------------------------------------
int main (int argc, char ** argv) {
encoderbuf buf;
std::iostream iostr(&buf);
iostr << 12345 << std::endl;
std::stringstream sstr;
iostr >sstr.rdbuf(); // EXCEPTION AT PROCESSING CHARACTER ''3''

std::string str = sstr.str();
std::cout << "main str = " << str << std::endl;
}
Output:
encoderbuf::overflow c = 49
encoderbuf::overflow c = 50
encoderbuf::overflow c = 51
encoderbuf::overflow c = 52
encoderbuf::overflow c = 53
encoderbuf::overflow c = 10
encoderbuf::underflow c = 49
encoderbuf::underflow c = 50
encoderbuf::underflow c = 51
popup: Unhandled exception at 0x00529bcc in hsl_d.exe: 0xC0000005:
Access violation reading location 0x00000000.




-

Jim Langston
ta ******* @ rocketmail.com


hs ******** @ gmail.com 写道:

>

有没有人尝试在Linux下运行此代码?我目前还没有方便的Linux机器,但我很想知道这是否严格来说是一个MS问题。
>
Has anyone tried running this code under Linux? I don''t have a Linux
machine handy at the moment, but I would be curious to know if this is
strictly a MS issue.



崩溃。

It crashes.


12月12日上午9:34,hsmit.h ... @ gmail.com写道:
On Dec 12, 9:34 am, hsmit.h...@gmail.com wrote:

我对下面的代码有些困难。我已将

剥离它至少是为了证明手头的问题。


编译器:MS Visual C ++ 2005 Express Edition(出现类似问题)

with 2008)


运行时库:所有多线程变体都被视为失败

[DLL / Static] | [Debug | Release]


目的:定义一个用户定义的流缓冲区,处理每个

的传入字符并将其转换为编码值。将

编码字符放入本地缓冲区以进行输出。最简单的情况

将是一个将每个字符转换为大写的编码器。一个更复杂的情况是编码器将纯文本编码为

base64编码(这不是一对一的字符编码,它是3

字符到4字符编码,这就是为什么内部缓冲区需要



问题:代码抛出一个

hsl_d.exe中的未处理异常:0xC0000005:访问冲突读取位置0x00000000。"

在encoderbuf :: underflow c = 51之后字符''3'已被读取。

这基本上告诉我,在IO

库的内部深处,某些东西被解除引用而未被分配。


问题:

1)其他编译器是否会出现这种情况? (需要测试)

2)这是IO库的问题吗? (我不太可能认为)

3)我做了些蠢事吗? (更有可能)如果是这样的话?


参考文献:

C ++标准库 - 教程和参考(13.13.3用户定义的
Stream Buffers)


代码:


#include< iostream>

#include < sstream>


class encoderbuf:public std :: streambuf {


char mCharBuf [128];

int mBufLen;

int mBufPos;

public:

// --------------- -----------------------------------------------

/ **默认构造函数* /

encoderbuf()

:std :: streambuf()

,mBufLen(0 )

,mBufPos(0)

{

}


// ---- -------------------------------------------------- --------

/ **传出数据* /

虚拟int_type下溢(){

int_type c = EOF;

if(mBufPos< mBufLen){

c = mCharBuf [mBufPos ++];

}

std :: cout<< " encoderbuf :: underflow c =" << c<< std :: endl;

返回c;

}
I''m having some difficulty with the following piece of code. I have
stripped it to it''s bare minimum to demonstrate the problem at hand.

Compiler: MS Visual C++ 2005 Express Edition (similar problem arises
with 2008)

Runtime Library: All multi-threaded variants have been seen to fail
[DLL/Static] | [Debug|Release]

Purpose: define a user defined stream buffer that processes each
incoming character and translates it to an encoded value. Place the
encoded character into a local buffer for output. The most simple case
would be an encoder that translates each character to upper case. A
more complicated case would be an encoder that encodes plain-text to
base64 encoding (this is not a one-to-one character encoding, it''s a 3
character to 4character encoding, this is why an internal buffer is
needed)

Problem: The code throws an "Unhandled exception at 0x00529bcc in
hsl_d.exe: 0xC0000005: Access violation reading location 0x00000000."
after the "encoderbuf::underflow c = 51" character ''3'' has been read.
This basically tells me that deep down in the internals of the IO
library something is being dereferenced that is not allocated.

Question(s):
1) Does this occur with other compilers? (requires testing)
2) Is this a problem with the IO library? (unlikely I think)
3) Am I doing something stupid? (more than likely) And if so what?

References:
C++ Standard Library - A Tutorial and Reference (13.13.3 User-Defined
Stream Buffers)

Code:

#include <iostream>
#include <sstream>

class encoderbuf : public std::streambuf {

char mCharBuf[128];
int mBufLen;
int mBufPos;
public:
//--------------------------------------------------------------
/** default constructor */
encoderbuf()
: std::streambuf()
, mBufLen(0)
, mBufPos(0)
{
}

//--------------------------------------------------------------
/** outgoing data */
virtual int_type underflow () {
int_type c = EOF;
if (mBufPos < mBufLen) {
c = mCharBuf[mBufPos++];
}
std::cout << "encoderbuf::underflow c = " << c << std::endl;
return c;
}



注意:此功能不符合要求对于

下溢。下溢必须返回该字符,将其留在流中的
。这通常涉及至少一个字符

缓冲区。在你的情况下,当然,你有一个更长的缓冲区,

所以你可以使用它:


int_type c = EOF;

if(mBufPos!= mBufLen){

setg(mCharBuf,mCharBuf + mBufPos,mCharBuf + mBufLen);

c = mCharBuf [mBufPos];

mBufPos = mBufLen;

}

返回c;


。虽然要解决的问题有所不同,但是在我的关于过滤streambuf'的文章中,你会找到关于

下溢和溢出要求的简短讨论。 br />
http://kanze.james .neuf.fr / articles-en.html)


// ---------------- ----------------------------------------------

/ **传入数据* /

虚拟int_type溢出(int_type c){

std :: cout<< encoderbuf :: overflow c =" << c<< std :: endl;

// TODO:在这里做编码

mCharBuf [mBufLen ++] = c;

返回c;

}

};
//--------------------------------------------------------------
/** incoming data */
virtual int_type overflow (int_type c) {
std::cout << "encoderbuf::overflow c = " << c << std::endl;
//TODO: do encoding here
mCharBuf[mBufLen++] = c;
return c;
}
};


// ---------------------------- ----------------------------------

int main(int argc,char * * argv){

encoderbuf buf;

std :: iostream iostr(& buf);

iostr<< 12345<< std :: endl;

std :: stringstream sstr;

iostr> sstr.rdbuf(); //处理字符'3'的例外情况

std :: string str = sstr.str();

std :: cout<< main str = << str<< std :: endl;

}
//--------------------------------------------------------------
int main (int argc, char ** argv) {
encoderbuf buf;
std::iostream iostr(&buf);
iostr << 12345 << std::endl;
std::stringstream sstr;
iostr >sstr.rdbuf(); // EXCEPTION AT PROCESSING CHARACTER ''3''
std::string str = sstr.str();
std::cout << "main str = " << str << std::endl;
}


输出:

encoderbuf :: overflow c = 49

encoderbuf :: overflow c = 50

encoderbuf :: overflow c = 51

encoderbuf :: overflow c = 52

encoderbuf :: overflow c = 53

encoderbuf :: overflow c = 10

encoderbuf :: underflow c = 49

encoderbuf :: underflow c = 50

encoderbuf :: underflow c = 51

popup:hsl_d.exe中0x00529bcc处的未处理异常:0xC0000005:

访问冲突读取位置0x00000000。
Output:
encoderbuf::overflow c = 49
encoderbuf::overflow c = 50
encoderbuf::overflow c = 51
encoderbuf::overflow c = 52
encoderbuf::overflow c = 53
encoderbuf::overflow c = 10
encoderbuf::underflow c = 49
encoderbuf::underflow c = 50
encoderbuf::underflow c = 51
popup: Unhandled exception at 0x00529bcc in hsl_d.exe: 0xC0000005:
Access violation reading location 0x00000000.



我的版本的下溢得到了正确的结果。

与g ++(在Linux下)和VC ++(在Windows下)。


可能发生的是实施,具有

读取带有下溢的字符,增加get指针

(gptr())。哪个是null,因为你从未设置它。下一个

时间,它将这个指针与egptr()进行比较,发现

它们不相等,并直接通过它进行访问。 (至少这是
,在Solaris下使用g ++会发生什么。至少,如果

输入路由使用sgetn,这就是发生的情况。)


在streambuf中实现输入的正常方法是使用至少一个字符的缓冲区来支持
覆盖下溢。

(The原因是允许简单直接支持

回拨。)


-

James Kanze(GABI软件)电子邮件:ja ********* @ gmail.com

Conseils eninformatiqueorientéeobjet/

Beratung in objektorientierter Datenverarbeitung

9个地方Sémard,78210 St.-Cyr-l''cocole,法国,+ 33(0)1 30 23 00 34

I get the correct results with my version of underflow. Both
with g++ (under Linux) and VC++ (under Windows).

What''s probably happening is that the implementation, having
read the character with underflow, increments the get pointer
(gptr()). Which is null, since you''ve never set it. The next
time around, it compares this pointer with egptr(), finds that
they aren''t equal, and accesses through it directly. (This is,
at least, what happens with g++ under Solaris. At least, if the
input routing is using sgetn, this is what happens.)

The normal way of implementing input in a streambuf is to
override underflow, using a buffer of at least one character.
(The reason for this is to allow simple and direct support for
putback.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l''école, France, +33 (0)1 30 23 00 34


这篇关于用于编码目的的用户定义的IO streambuf问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆