在 class 对象段错误中使用 boost::interprocess,为什么?
using boost::interprocess in class object segfaults, why?
我正在尝试让一些代码工作,这些代码使用 class 来设置和管理共享内存,并从我的主程序调用 class 的对象。所有代码直接在我的 main() 中时都有效,但是当我在 class 中设置它并实例化该 class 的对象时,我得到了一个段错误。
我不知道为什么或如何解决它?
此处的第一个示例显示了在我的 main() 函数中正常运行的示例:
#include <boost/interprocess/managed_shared_memory.hpp>
using namespace boost::interprocess;
typedef struct teststruct {
int testint=9;
};
typedef std::pair<teststruct, int> memsh_teststruct;
int main(int argc, char *argv[])
{
printf("inMain0\n");
struct shm_remove
{
shm_remove() { shared_memory_object::remove("testShare"); }
~shm_remove(){ shared_memory_object::remove("testShare"); }
} remover;
//Construct managed shared memory
managed_shared_memory segment(create_only, "testShare", 65536);
teststruct myTeststruct;
memsh_teststruct *inst_teststruct;
inst_teststruct = segment.construct<memsh_teststruct>
("name_myTeststruct")
(myTeststruct, 0);
printf("construct_ptr: %p \n", &inst_teststruct->first);
inst_teststruct->first.testint = 1234;
printf("construct_val: %d\n", inst_teststruct->first.testint);
int mainInt;
printf("inMain1\n");
mainInt = inst_teststruct->first.testint;
printf("mainInt: %d\n", mainInt);
printf("inMain2\n");
}
输出看起来不错,像这样:
construct_ptr: 0x7f0d41834118
construct_val: 1234
inMain0
inMain1
mainInt: 1234
inMain2
这是设置完全相同共享内存的第二个示例,但使用 class。
#include <boost/interprocess/managed_shared_memory.hpp>
using namespace boost::interprocess;
typedef struct teststruct {
int testint=9;
};
typedef std::pair<teststruct, int> memsh_teststruct;
class testclass{
public:
testclass();
bool something(int in);
teststruct myTeststruct;
memsh_teststruct *inst_teststruct;
};
testclass::testclass()
{
struct shm_remove
{
shm_remove() { shared_memory_object::remove("testShare"); }
~shm_remove(){ shared_memory_object::remove("testShare"); }
} remover;
//Construct managed shared memory
managed_shared_memory segment(create_only, "testShare", 65536);
inst_teststruct = segment.construct<memsh_teststruct>
("name_myTeststruct")
(myTeststruct, 0);
printf("construct_ptr: %p \n", &inst_teststruct->first);
inst_teststruct->first.testint = 1234;
printf("construct_val: %d\n", inst_teststruct->first.testint);
}
int main(int argc, char *argv[])
{
printf("inMain0\n");
int mainInt;
testclass testclassObj;
printf("inMain1\n");
mainInt = testclassObj.inst_teststruct->first.testint;
printf("mainInt: %d\n", mainInt);
printf("inMain2\n");
}
但是第二个示例出现段错误,这是输出:
inMain0
construct_ptr: 0x7fa222d37118
construct_val: 1234
inMain1
Segmentation fault (core dumped)
... 那么为什么调用
mainInt = testclassObj.inst_teststruct->first.testint;
来自 main() 导致段错误?
我还尝试了一些其他变体,例如在我的 class 中定义其他函数来与共享内存变量交互,它也会出现段错误。
如果我不得不猜测发生了什么,我感觉共享内存正在关闭或者在我预期之前发生了什么,可能是在退出 testclass() 构造函数之后。但是,我不知道避免这种情况的正确方法,以便在清理整个 testclassObj 对象时从 main() 返回时关闭共享内存。
另一方面,也许我完全错了?
谢谢,
B
编辑:
EDIT2:最后一次编辑被删除,我的错误是无关紧要的,由于我在 Sean 的回答中对评论线程做了一些愚蠢的事情。
您完全正确地猜测共享内存会在您预期之前关闭。
managed_shared_memory
在testclass::testclass
中构造,在构造函数结束时超出范围,关闭共享内存,但留下inst_teststruct
指向共享内存使用的地方成为。
只要有指向它的指针,您就必须保留 segment
。最简单的方法可能是将 segment
提升为 testclass
的 class 成员,如下所示:
class testclass {
public:
testclass();
managed_shared_memory segment;
teststruct myTeststruct;
memsh_teststruct *inst_teststruct;
};
testclass::testclass()
: segment(create_only, "testShare", 65536) //< Construct managed shared memory
{
struct shm_remove {
shm_remove() { shared_memory_object::remove("testShare"); }
~shm_remove() { shared_memory_object::remove("testShare"); }
} remover;
inst_teststruct = segment.construct<memsh_teststruct>
("name_myTeststruct")
(myTeststruct, 0);
printf("construct_ptr: %p \n", &inst_teststruct->first);
inst_teststruct->first.testint = 1234;
printf("construct_val: %d\n", inst_teststruct->first.testint);
}
但是,您必须考虑如何最好地管理共享内存的生命周期,特别是考虑到将涉及另一个进程。
我正在尝试让一些代码工作,这些代码使用 class 来设置和管理共享内存,并从我的主程序调用 class 的对象。所有代码直接在我的 main() 中时都有效,但是当我在 class 中设置它并实例化该 class 的对象时,我得到了一个段错误。
我不知道为什么或如何解决它?
此处的第一个示例显示了在我的 main() 函数中正常运行的示例:
#include <boost/interprocess/managed_shared_memory.hpp>
using namespace boost::interprocess;
typedef struct teststruct {
int testint=9;
};
typedef std::pair<teststruct, int> memsh_teststruct;
int main(int argc, char *argv[])
{
printf("inMain0\n");
struct shm_remove
{
shm_remove() { shared_memory_object::remove("testShare"); }
~shm_remove(){ shared_memory_object::remove("testShare"); }
} remover;
//Construct managed shared memory
managed_shared_memory segment(create_only, "testShare", 65536);
teststruct myTeststruct;
memsh_teststruct *inst_teststruct;
inst_teststruct = segment.construct<memsh_teststruct>
("name_myTeststruct")
(myTeststruct, 0);
printf("construct_ptr: %p \n", &inst_teststruct->first);
inst_teststruct->first.testint = 1234;
printf("construct_val: %d\n", inst_teststruct->first.testint);
int mainInt;
printf("inMain1\n");
mainInt = inst_teststruct->first.testint;
printf("mainInt: %d\n", mainInt);
printf("inMain2\n");
}
输出看起来不错,像这样:
construct_ptr: 0x7f0d41834118
construct_val: 1234
inMain0
inMain1
mainInt: 1234
inMain2
这是设置完全相同共享内存的第二个示例,但使用 class。
#include <boost/interprocess/managed_shared_memory.hpp>
using namespace boost::interprocess;
typedef struct teststruct {
int testint=9;
};
typedef std::pair<teststruct, int> memsh_teststruct;
class testclass{
public:
testclass();
bool something(int in);
teststruct myTeststruct;
memsh_teststruct *inst_teststruct;
};
testclass::testclass()
{
struct shm_remove
{
shm_remove() { shared_memory_object::remove("testShare"); }
~shm_remove(){ shared_memory_object::remove("testShare"); }
} remover;
//Construct managed shared memory
managed_shared_memory segment(create_only, "testShare", 65536);
inst_teststruct = segment.construct<memsh_teststruct>
("name_myTeststruct")
(myTeststruct, 0);
printf("construct_ptr: %p \n", &inst_teststruct->first);
inst_teststruct->first.testint = 1234;
printf("construct_val: %d\n", inst_teststruct->first.testint);
}
int main(int argc, char *argv[])
{
printf("inMain0\n");
int mainInt;
testclass testclassObj;
printf("inMain1\n");
mainInt = testclassObj.inst_teststruct->first.testint;
printf("mainInt: %d\n", mainInt);
printf("inMain2\n");
}
但是第二个示例出现段错误,这是输出:
inMain0
construct_ptr: 0x7fa222d37118
construct_val: 1234
inMain1
Segmentation fault (core dumped)
... 那么为什么调用
mainInt = testclassObj.inst_teststruct->first.testint;
来自 main() 导致段错误?
我还尝试了一些其他变体,例如在我的 class 中定义其他函数来与共享内存变量交互,它也会出现段错误。
如果我不得不猜测发生了什么,我感觉共享内存正在关闭或者在我预期之前发生了什么,可能是在退出 testclass() 构造函数之后。但是,我不知道避免这种情况的正确方法,以便在清理整个 testclassObj 对象时从 main() 返回时关闭共享内存。
另一方面,也许我完全错了?
谢谢, B
编辑: EDIT2:最后一次编辑被删除,我的错误是无关紧要的,由于我在 Sean 的回答中对评论线程做了一些愚蠢的事情。
您完全正确地猜测共享内存会在您预期之前关闭。
managed_shared_memory
在testclass::testclass
中构造,在构造函数结束时超出范围,关闭共享内存,但留下inst_teststruct
指向共享内存使用的地方成为。
只要有指向它的指针,您就必须保留 segment
。最简单的方法可能是将 segment
提升为 testclass
的 class 成员,如下所示:
class testclass {
public:
testclass();
managed_shared_memory segment;
teststruct myTeststruct;
memsh_teststruct *inst_teststruct;
};
testclass::testclass()
: segment(create_only, "testShare", 65536) //< Construct managed shared memory
{
struct shm_remove {
shm_remove() { shared_memory_object::remove("testShare"); }
~shm_remove() { shared_memory_object::remove("testShare"); }
} remover;
inst_teststruct = segment.construct<memsh_teststruct>
("name_myTeststruct")
(myTeststruct, 0);
printf("construct_ptr: %p \n", &inst_teststruct->first);
inst_teststruct->first.testint = 1234;
printf("construct_val: %d\n", inst_teststruct->first.testint);
}
但是,您必须考虑如何最好地管理共享内存的生命周期,特别是考虑到将涉及另一个进程。