简体   繁体   English

破坏std :: stringbuf导致访问冲突

[英]destruction of std::stringbuf causing access violation

I have a c++ class that roughly looks like this (see code below). 我有一个大致像这样的c ++类(请参见下面的代码)。 It has an input buffer and an output buffer using a std::stringbuf. 它具有使用std :: stringbuf的输入缓冲区和输出缓冲区。 Because I also want access to the raw buffer, I set the underlying buffer with my own user-defined byte array using std::stringbuf.pubsetbuf(). 因为我也想访问原始缓冲区,所以我使用std :: stringbuf.pubsetbuf()用我自己的用户定义的字节数组设置基础缓冲区。

All things seem to work fine, until I no longer need the object but when the object is destructed, it causes my program to crash with an access violation. 一切似乎都正常,直到我不再需要该对象为止,但是当对象被破坏时,它将导致我的程序因访问冲突而崩溃。

I traced it down to the piece of code as illustrated below. 我将其追溯到如下所示的代码段。 It looks to me that the stringbuf is somehow cleaning up my user-defined byte array itself?? 在我看来,stringbuf某种程度上正在清理用户定义的字节数组本身? My program doesn't crash when I remove the code in the destrcutor of my class to free the byte array I previously allocated in the constructor. 当我删除类的析构函数中的代码以释放先前在构造函数中分配的字节数组时,程序不会崩溃。

Any advice on this, please? 有什么建议吗? Am I wrongly using the std::stringbuf? 我在错误地使用std :: stringbuf吗? I'm using the Borland 5.0 compiler (I know it's a very old and outdated compiler, but I have to stick to this compiler for a while). 我正在使用Borland 5.0编译器(我知道它是一个非常老旧且过时的编译器,但是我不得不坚持使用一段时间。)

class SomeClass {

private:

    char *mIBuf;
    char *mOBuf;

    std::stringbuf mIBufStream;
    std::stringbuf mOBufStream;

public:

    SomeClass(int iBufSize, int oBufSize) :
      mIBuf(), mOBuf(),
      mIBufStream(), mOBufStream()
    {
        mIBuf = (char*)malloc(iBufSize);
        mOBuf = (char*)malloc(oBufSize);

        mIBufStream.pubsetbuf(mIBuf, iBufSize);
        mIBufStream.pubseekpos(0);

        mOBufStream.pubsetbuf(mOBuf, oBufSize);
        mOBufStream.pubseekpos(0);
    }

    virtual ~SomeClass()
    {
        free(mIBuf);
        free(mOBuf)
    }

};

According to the Standard stringbuf doesn't have a destructor of its own and streambuf 's destructor does nothing. 根据标准, stringbuf没有自己的析构函数, streambuf的析构函数不执行任何操作。 Your old compiler and library may or may not be following that; 您的旧编译器和库可能会或可能不会遵循; the evidence is that it isn't. 有证据表明事实并非如此。

Well, in principle you are doing something wrong. 好吧,原则上您在做错事。 When you call pubsetbuf you are giving that object permission to use that buffer for as long as the object lives, or until you change its buffer again. 调用pubsetbuf您授予该对象使用该缓冲区的权限,直到该对象存在为止,或者直到您再次更改其缓冲区为止。

Looking at your destructor, you aren't keeping your side of the bargain. 看着你的破坏者,你并没有站在讨价还价的一边。

virtual ~SomeClass()
{
    free(mIBuf);
    free(mOBuf); // <- missing semicolon in your code

    // the stringbuf objects are still alive here
}   // they get automatically destroyed here

One option is to arrange for the stringbuf objects to be destroyed before you free the buffers ( char* buffer deallocation will need to be done by a helper class, either a base class or a member declared before the stringbuf -- std::vector<char> would be a good choice). 一种选择是安排在释放缓冲区之前销毁stringbuf对象( char*缓冲区释放将需要由辅助类完成,该辅助类可以是基类,也可以是在stringbuf之前声明的成员stringbuf std::vector<char>是一个不错的选择)。

Or, you can let the stringbuf know that you're revoking its permission to use your memory: 或者,您可以让stringbuf知道您正在撤销其使用内存的权限:

virtual ~SomeClass()
{
    mIBufStream.pubsetbuf(0, 0);
    mOBufStream.pubsetbuf(0, 0);

    // the stringbufs cannot use your memory any longer

    free(mIBuf);
    free(mOBuf);
}

Well, to answer my own question... (and thanks to Ben Voight for his useful advise). 好吧,回答我自己的问题...(并感谢Ben Voight的有用建议)。 Until someone else would prove me wrong, I've come to the conclusion that my issue is implementation specific and that the Borland 5.0 STL library may not be conform the standard. 除非别人证明我错了,否则我得出的结论是,我的问题是特定于实现的,并且Borland 5.0 STL库可能不符合该标准。

I tested my sample class. 我测试了我的示例课。 I extracted it and put it in a small test program as listed below (no other code that would possibly corrupt the memory). 我将其提取并放入下面列出的小型测试程序中(没有其他可能破坏内存的代码)。 I compiled 1 version with Visual Studio 2013, the other with Borland 5.0. 我使用Visual Studio 2013编译了一个版本,另一个使用Borland 5.0编译了一个版本。 The one compiled with Visual Studio runs just fine. 使用Visual Studio编译的程序运行良好。 The one compiled with Borland crashes after the 1st iteration. 用Borland编译的代码在第一次迭代后崩溃。

#include <iostream>

include 包括

class SomeClass { class SomeClass {

char *mIBuf;
char *mOBuf;

std::stringbuf mIBufStream;
std::stringbuf mOBufStream;

public: 上市:

SomeClass(int iBufSize, int oBufSize) : mIBuf(NULL), mOBuf(NULL), mIBufStream(), mOBufStream() {
    mIBuf = (char*)malloc(iBufSize);
    mOBuf = (char*)malloc(oBufSize);

    mIBufStream.pubsetbuf(mIBuf, iBufSize);
    mIBufStream.pubseekpos(0);

    mOBufStream.pubsetbuf(mOBuf, oBufSize);
    mOBufStream.pubseekpos(0);
}

virtual ~SomeClass() {
    mIBufStream.pubsetbuf(0, 0);
    mOBufStream.pubsetbuf(0, 0);

    free(mIBuf);
    free(mOBuf);
}

}; };

int main(int argc, char* argv[])
{
    for (int x = 0; x < 1000; x++) {
        SomeClass SomeClass(128 * 1024, 128 * 1024);
        std::cout << "Pass " << x + 1 << std::endl;
    }

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM