c++ 在构造函数中初始化消息队列时的EINVAL

llycmphe  于 2023-05-19  发布在  其他
关注(0)|答案(1)|浏览(106)

我需要在学校的一个项目中使用消息队列。我写了一个 Package 器,但是如果我把mq_open()放在constructor中,mq_open()就失败了(它在主...)。
以下是valgrind错误:

==105030== Syscall param mq_open(attr->mq_maxmsg) points to unaddressable byte(s)
==105030==    at 0x4C9076D: mq_open@@GLIBC_2.34 (mq_open.c:51)
==105030==    by 0x10BEEC: MessageQueue::MessageQueue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (MessageQueue.cpp:13)
==105030==    by 0x10B308: main (main.cpp:9)
==105030==  Address 0x6c is not stack'd, malloc'd or (recently) free'd
==105030==
==105030== Syscall param mq_open(attr->mq_msgsize) points to unaddressable byte(s)
==105030==    at 0x4C9076D: mq_open@@GLIBC_2.34 (mq_open.c:51)
==105030==    by 0x10BEEC: MessageQueue::MessageQueue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (MessageQueue.cpp:13)
==105030==    by 0x10B308: main (main.cpp:9)
==105030==  Address 0x74 is not stack'd, malloc'd or (recently) free'd

下面是有问题的源代码:

// MessageQueue.hpp

#pragma once

#include <string>
#include <mqueue.h>

class MessageQueue {
    public:
        MessageQueue(const std::string &name);
        ~MessageQueue(void);

        bool is_open(void) const;

    protected:
        mqd_t _mq;
};

// MessageQueue.cpp

MessageQueue::MessageQueue(const std::string &name)
{
    std::string n = name;

    if (n[0] != '/') {
        n = "/" + name;
    }
    _mq = mq_open(name.c_str(), O_RDWR | O_CREAT);
}

bool MessageQueue::is_open(void) const
{
    return _mq != -1;
}

MessageQueue::~MessageQueue(void)
{
    if (is_open()) {
        mq_close(_mq);
    }
}

// main.cpp

#include <iostream>

#include "MessageQueue.hpp"

int main(int argc, char *argv[])
{
    MessageQueue a("/abcd");

    std::cout << a.is_open() << std::endl;
    return 0;
}

这是可行的:

#include <iostream>

#include "MessageQueue.hpp"

int main(int argc, char *argv[])
{
    mqd_t _mq = mq_open("/abcd", O_RDWR | O_CREAT);

    std::cout << (_mq != -1) << std::endl;
    return 0;
}

我刚刚发现,如果我创建一个MessageQueue,然后使用mq_open(),它也不工作...
有什么想法吗?提前感谢!

4uqofj5v

4uqofj5v1#

有人在我学校找到的。
它沿着在man中:
如果在oflag中指定了O_CREAT,则必须提供两个额外的参数。
我不知道确切的原因,但在主要的,参数得到一个默认值,而不是在构造函数。我认为scope(vtables...?).

相关问题