Re: place stl container object on shared memory
Hi, Jeff
Thanks for the advice. I modify my code where I "delete" pStr to pStr-
~String() and my test program is good. I compiled your sample code in
SunOS 5.10 and got this error:
"shm.h", line 62: Error: Formal argument 1 of type char* in call to
shmdt(char*) is being passed void*.
"shm.h", line 85: Where: While instantiating "static
dbtouch::shared_memory<420, 1048576>::detach(void*)".
"shm.h", line 85: Where: Instantiated from non-template code.
It is
static void detach(void_pointer memory) {
check_posix(shmdt(memory), "shmdt");
}
which has problem. Please take a look.
Thanks,
YE LIU
On Feb 24, 4:09 pm, Jeff Schwab <j...@schwabcenter.com> wrote:
dbtouch wrote:
I am trying to place an STL container object on shared memory
String* pStr=new(ptr)String(); // segment fault!!!
No, that's not where the segv is occurring.
if (pStr) {
delete pStr;
This is. Delete doesn't just call the destructor, it also tries to fre=
e
the memory. That's not what you want here. You just want to call th=
e
destructor.
pStr->~string();
printf("test is good\n");
}
You seem to be new to C++, and have carried a lot of C with you. I'm
posting a modern C++ version of your code here, in the hope that it will
help you find "the C++ way." Good luck.
/* POSIX */
extern "C" {
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
}
/* C++ Standard */
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <string>
/* Dbtouch library code. */
namespace dbtouch {
typedef void* void_pointer;
template<std::size_t Size>
void check_posix(long i, char const (&command_name)[Size]) {
if (i == -1L) {
throw std::runtime_error(
std::string( command_name ) +
std::strerror(errno) );
}
}
template<int Mode, std::size_t Size>
class shared_memory
{
typedef void const* void_const_pointer;
typedef shmid_ds* shmid_ds_pointer;
static int create() {
int const shmid =
shmget(IPC_PRIVATE , Size , Mode | IPC=
_CREAT);
check_posix(shmid, "shmget");
return shmid;
}
static void_pointer attach(int shmid) {
void_pointer const memory =
shmat(shmid, void_const_pointe=
r( ), Mode);
check_posix(reinterpret_cast<long>(memory), "s=
hmat");
return memory;
}
static void detach(void_pointer memory) {
check_posix(shmdt(memory), "shmdt");
}
static void destroy(int shmid) {
check_posix(
shmctl(shmid, IPC_RMID, shmid_=
ds_pointer( ))
, "shmctl");
}
int m_shmid;
void_pointer m_memory;
public:
shared_memory( )
: m_shmid( create() )
, m_memory( attach(m_shmid) ) { }
~shared_memory() {
detach(m_memory);
destroy(m_shmid);
}
void_pointer get() {
return m_memory;
}
};
}
/* Test of dbtouch library. */
/* Configuration. */
namespace {
typedef std::string object;
int const mode = 0644;
std::size_t const size = 1024 * 1024;
}
void unchecked_main() {
dbtouch::shared_memory<mode, size> buffer;
if (object* const p = new(buffer.get()) object) {
p->~object();
std::cout << "test is good\n";
}
}
int main() try {
unchecked_main();
return EXIT_SUCCESS;} catch (std::exception const& x) {
std::cerr << "std::exception: " << x.what() << '\n';
return EXIT_FAILURE;
}- Hide quoted text -
- Show quoted text -