我有一个带有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位编译器引起的堆栈或堆问题吗?