错误:稍后使用时成员指针超出范围

时间:2019-08-21 22:37:09

标签: object pointers memory boost shared

我有一个带有Boost共享内存对象的类,我试图在初始化时获取内存地址,以便稍后使用。但是指针在以后使用时变得越界。我也尝试过使用const指针。

每次需要使用指针时,我都会尝试动态投射。它有效,但我认为这会影响性能。这是由MinGW 32位版本编译的。我曾经有一个没有此问题的64位编译器。指针可以在以后使用。

#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/move/move.hpp>
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <thread>
#include <unistd.h>

using namespace boost::interprocess;

class sram
{
public:
    shared_memory_object m_shm;
    char* m_ptr;
    sram():
        m_shm(shared_memory_object()),
        m_ptr(nullptr)
        {}
    sram(size_t t, bool owner, const char* name):
        m_shm(shared_memory_object()),
        m_ptr(nullptr)
    {
        if(owner)
        {
            shared_memory_object::remove(name);
            try
            {
                m_shm = shared_memory_object(open_or_create,name, read_write);
                m_shm.truncate (t*sizeof(char));
                mapped_region region(m_shm, read_write);
                m_ptr = static_cast<char*>(region.get_address());
            }
            catch(...)
            {
                std::cout<<"Error open_or_create: "<<name<<std::endl;
                throw("open_or_create");
            }
        }
        else
        {
            try
            {
                m_shm =shared_memory_object(open_only, name, read_only);
                mapped_region region(m_shm, read_only);
                m_ptr = static_cast<char*>(region.get_address());
            }
            catch(...)
            {
                std::cout<<"Error open_only: "<<name<<std::endl;
                throw("open_only");
            }
        }

        if(m_ptr==nullptr)
        {
            std::cout<<"m_ptr null "<<name<<std::endl;
            throw("m_ptr null");
        }
    }
    sram(const sram&&  x)
    {
        m_shm =  (BOOST_RV_REF(shared_memory_object)) x.m_shm;
        m_ptr   = x.m_ptr;
    }
    virtual ~sram(){}

    const char* get_name() const
    {
        return m_shm.get_name();
    }
    const shared_memory_object&
    get_shm() const
    {
        return m_shm;
    }
    void write2(char *buff, int k)
    {
        mapped_region region(m_shm, read_write);
        char* m_ptr1 = static_cast<char*>(region.get_address());
        memcpy((void*)m_ptr1,(void*)buff,k);
    }
    void write1(char *buff, int k)
    {  ///use saved memory ptr
        memcpy((void*)m_ptr,(void*)buff,k);

    }
    void read1(char *buff, int k)
    {
        ///use saved memory ptr
        memcpy((void*)buff, (void*)m_ptr,k);
    }
    void read2(char *buff, int k)
    {
        mapped_region region(m_shm, read_only);
        char* m_ptr1 = static_cast<char*>(region.get_address());
        memcpy((void*)buff, (void*)m_ptr1,k);
    }
};
///use version 2 to write.  Works
///this ptr will cast dynamically
void write2()
{
    int len=200;
    char bp[len];
    sram aa(len,true,"test");
    int i=0;
    while(true)
    {
        memset(bp,0,len*sizeof(char));
        sprintf(bp,"%d",i++);
        std::cout<<"write2 " <<bp<<std::endl;
        aa.write2(bp,len);
    }
};
///use version 1 to write
///the ptr is saved one.  Not working
void write1()
{
    int len=200;
    char bp[len];
    sram aa(len,true,"test");
    int i=0;
    while(true)
    {
        memset(bp,0,len*sizeof(char));
        sprintf(bp,"%d",i++);
        std::cout<<"write2 " <<bp<<std::endl;
        aa.write1(bp,len);
    }
};
///not working, pointer out of bounds
void read1()
{
    int len=200;
    char bp[len];
    sram aa(len,false,"test");
    int i=0;
    while(true)
    {
        memset(bp,0,len*sizeof(char));
        aa.read1(bp,len);
        std::cout<<"read "<<i<<" == "<<bp<<std::endl;
        i++;
    }
};
///works
void read2()
{
    int len=200;
    char bp[len];
    sram aa(len,false,"test");
    int i=0;
    while(true)
    {
        memset(bp,0,len*sizeof(char));
        aa.read2(bp,len);
        std::cout<<"read "<<i<<" == "<<bp<<std::endl;
        i++;
    }
};
int main (int argc, char**argv)
{

    int option = 0;
    if (argc>1) option = atol(argv[1]);
    switch (option)
    {
        case 0: ///use version 2 to write
        {
            write2();
        }
        break;
        case 1: ///use version 1 to write
        {
            write1();///crash
        }
        break;
        case 2:
        {
            read2();
        }
        break;
        case 3:
        {
            read1();///crash
        }
        break;
        default:
            std::cout<<"usage : "<<argv[0]<<" # \n";
    }
    return 0;
};

何时使用该代码,请打开两个控制台,并提供0、1、2或3作为命令行参数。 0或1是发送数据。 2或3是接收数据。 对于发送数据,版本write2()有效。用于读取数据。 read2()有效。对于使用保存的指针的版本,它不起作用。我曾经有一个旧的64位MinGW编译器。它没有这个问题。这是由于64位设备上的32位编译器引起的堆栈或堆问题吗?

0 个答案:

没有答案