在C结构中的std :: vector

时间:2018-06-13 18:47:40

标签: c++ malloc stdvector

typedef struct _route_timer_info_t {
    task_timer * withdraw_timer;
    std::vector<sockaddr_union> mcast_addr_list;
    uint32_t route_block_id;
    uint32_t bgp_device_id;
}route_timer_info_t;

我的代码中有上述结构。我已经指向上面的结构并从堆中分配了内存。

route_timer_info_t *route_timer=(route_timer_info_t *)malloc(sizeof(route_timer_info_t));

现在填充向量,我正在做

route_timer->mcast_addr_list.push_back(some_item)

在第一次运行时,向量的大小正确 - 我正在推动,但是当在第二次运行时整个结构被分配内存时,向量的大小正在变成一些很大的垃圾值。怎么可能出错?我也尝试过清除矢量,但没有帮助。

3 个答案:

答案 0 :(得分:0)

因为您使用malloc来分配内存而不是new,所以std::vector的构造函数从未被调用过,因此它从未正确初始化。

始终使用new

route_timer_info_t *route_timer = new route_timer_info_t;

答案 1 :(得分:0)

Malloc只分配一块内存,这是不开发的。对于C代码,这通常是成员。在C ++中,有一个构造函数的概念。

默认情况下,每个类和结构都会获得它,并且编译器应该以最佳方式对其进行优化。 在堆栈上构造实例或使用new运算符时,调用它会隐式发生。

在某些特殊情况下,您希望在前面分配内存并在以后构建。 (std :: vector这样做)你可以这样做:

auto validPtr = new (&route_timer->mcast_addr_list)   std::vector<sockaddr_union>();

更好的是直接简单地打电话给新人:

new route_timer_info_t();

为了确保将所有成员初始化为已知值,我建议明确初始化所有成员:

struct _route_timer_info_t {
    task_timer * withdraw_timer{nullptr};
    std::vector<sockaddr_union> mcast_addr_list{};
    uint32_t route_block_id{0};
    uint32_t bgp_device_id{0};
};

为了完成故事,从C ++ 14开始,不建议再直接调用new,而是直接通过以下方式创建一个唯一的指针:

 std::make_unique<route_timer_info_t>();

在所有这些情况下,包括您的原始示例,结构都与C兼容。

答案 2 :(得分:0)

正如其他答案中所提到的,主要问题是因为对象不是&#34;构造&#34;。所提到的在new本身上调用struct运算符的解决方案是有效的。但由于某种原因,如果struct需要malloc或者它不在您的控制范围内,您可以使用new运算符在该内存中显式构造对象。请参阅第三种形式here

您可以将矢量构造为 -

new (&(route_timer->mcast_addr_list)) std::vector<sockaddr_union>;

您现在可以使用向量,就好像它是使用new运算符实际创建的一样。

相关问题