【发布时间】:2020-03-20 16:03:48
【问题描述】:
#include <iostream>
#include <vector>
#include <mutex>
struct STRU_Msg
{
std::string name;
void *vpData;
};
class CMSG
{
public:
template <typename T>
int miRegister(std::string name)
{
STRU_Msg msg;
msg.name = name;
msg.vpData = malloc(sizeof(T));
msgtable.push_back(msg);
std::cout << "registeratio ok\n";
return 0;
}
template <typename T>
int miPublish(std::string name, T tData)
{
for (int i = 0; i < msgtable.size(); i++)
{
if (!name.compare(msgtable[i].name))
{
(*(T *)msgtable[i].vpData) = tData;
std::cout << "SUccess!\n";
return 0;
}
else
{
std::cout << "cannot find\n";
return 0;
}
}
}
private:
std::vector<STRU_Msg> msgtable;
};
int main()
{
CMSG message;
std::string fancyname = "xxx";
std::vector<float> v;
// message.miRegister< std::vector<float> >(fancyname);
// for (int i = 0; i < 1000; i++)
// {
// v.push_back(i);
// }
// std::cout << "v[0]: " << v[0] << ", v[-1]: " << v[v.size()-1] << '\n';
// message.miPublish< std::vector<float> >(fancyname, v);
for (int i = 0; i < 1000; i++)
{
v.push_back(i);
}
std::cout << "v[0]: " << v[0] << ", v[-1]: " << v[v.size()-1] << '\n';
message.miRegister< std::vector<float> >(fancyname);
message.miPublish< std::vector<float> >(fancyname, v);
return 0;
}
我想要实现的是编写一个简单的发布/订阅(如 ROS)系统,我使用 void 指针,以便它适用于所有数据类型。这是简化的代码。
如果我发布一个 int,它可以正常工作,但真正让我困惑的是:
- 如果我传递一个长向量(如这段代码),它会给我 “分段错误(核心转储)”错误。
- 如果我定义了“注册”和“发布”之间的向量(例如 注释部分),此错误消失。
- 如果我使用更短的向量,比如大小为 10,无论我在哪里定义 它,我的代码运行顺利。
我在 Linux 中使用 g++。
请帮我修复我的代码并解释为什么会发生上述行为,谢谢!
【问题讨论】:
-
为什么不在
CMSG中声明STRU_Msg并使用T *tpData而不是void *vpData? -
malloc在 C++ 中的用例很少(这不是其中之一),更喜欢new... 但void*也是一种代码味道。 -
你的循环只迭代一个第一个元素......
-
而您的“工作”代码只是您的代码的每个变体所表现出的未定义行为的一种可能输出。
-
据我所知,您使用
malloc分配sizeof(std::vector<float>)字节的内存,然后将其转换为std::vector<float>(以便将另一个向量复制到其中,是对std::vector<float>::operator=(...)) 的调用,并期待合理的结果。那行不通(它是UB),您需要实际构建第一个向量;使用new而不是malloc。
标签: c++ c++11 vector void-pointers