结构体包含 std::list 未初始化问题

结构体包含 std::list 未初始化问题

由于在编写C++代码时,用到std::list<> ,而喜欢用malloc来进行结构体分配内存出现的问题。

struct play_list{
    bool is_started;
    int g_operate_id;
    char *name;
    CRITICAL_SECTION    play_operate_section;
    std::list<play_operate*> play_operate_list; //list
};

原因:

 std::list/map等都属于c++的类,当用malloc的时候并未进行初始化,而用memset(&play_list,0,sizeof(play_list)) 进行初始化又会把list中的一些字段给赋值为null。

修正:

play_list * plist = new play_list();

关于new play_list() 和new play_list区别 :

 new 分配内存有时会初始化,有时却不会,这依赖于是否是POD(Plain old data)类型,或者它是否是包含POD成员、使用编译器生成默认构造函数的类。

 附:POD类型
 POD是Plain old data的缩写,它是一个struct或者类,且不包含构造函数、析构函数以及虚函数。

 维基百科给出了更加详细的解释:
 C++的POD类型或者是一个标量值,或者是一个POD类型的类。POD class没有用户定义的析构函数、拷贝构造函数和非静态的非POD类型的数据成员。而且,POD class必须是一个aggregate,没有用户定义的构造函数,没有私有的或者保护的非静态数据,没有基类或虚函数。它只是一些字段值的集合,没有使用任何封装以及多态特性。
  • C++中的三种初始化方式
    • zero-initialization
    • default-initialization
    • value-initialization(C++2003标准中新引入)

看一段代码:

#include<iostream>

using namespace std;

struct A { int m; }; // POD  
struct B { ~B(){}; int m; }; // non-POD, compiler generated default ctor  
struct C { C() : m() {}; ~C(){}; int m; }; // non-POD, default-initialising m  

int main()
{
    A *aObj1  = new A;
    A *aObj2  = new A();
    cout  << aObj1->m  << endl;
    cout  << aObj2->m  << endl;

    B *bObj1  = new B;
    B *bObj2  = new B();
    cout  << bObj1->m  << endl;
    cout  << bObj2->m  << endl;

    C *cObj1  = new C;
    C *cObj2  = new C();//默认构造已重写
    cout  << cObj1->m  << endl;
    cout  << cObj2->m  << endl;

    delete aObj1;
    delete aObj2;
    delete bObj1;
    delete bObj2;
    delete cObj1;
    delete cObj2;

    return 0;
}

运行结果:
在vs2008 或2013中运行结果:

这里写图片描述

new A:不确定的值
new A():zero-initialize
new B:默认构造(B::m未被初始化)
new B():默认构造(B::m未被初始化)
new C:默认构造(C::m被zero-initialize)
new C():默认构造(C::m被zero-initialize)

如果用兼容C++03的编译器,比如G++结果:
这里写图片描述

new A:不确定的值
new A():value-initialize A,由于是POD类型所以是zero initialization
new B:默认构造(B::m未被初始化)
new B():value-initialize B,zero-initialize所有字段,因为使用的默认构造函数
new C:default-initialize C,调用默认构造函数
new C():value-initialize C,调用默认构造函数

总而言之呢,大多情况下最好使用new A() 来分配内存喽~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++结构体也可以包含一个列表(list)类型的成员变量。对于这样的结构体,我们可以使用以下方式进行列表初始化: ```c++ struct MyStruct { std::list<int> myList; // 声明一个list成员变量 }; MyStruct myObj = { {1, 2, 3, 4} }; // 使用列表初始化结构体进行初始化 ``` 在上面的代码,我们声明了一个结构体 `MyStruct`,其包含一个 `std::list<int>` 类型的成员变量 `myList`。我们使用花括号 `{}` 对 `myObj` 进行了初始化,并将列表 `{1, 2, 3, 4}` 作为参数传递给了 `myList`。 需要注意的是,这里使用了两层花括号进行初始化,因为列表成员变量需要自己的一对花括号。如果我们只使用一对花括号进行初始化,编译器会认为这是在初始化结构体本身,而不是其的成员变量,从而导致编译错误。 除了以上方式,我们还可以在结构体的构造函数进行列表初始化,例如: ```c++ struct MyStruct { std::list<int> myList; MyStruct(std::initializer_list<int> list) : myList(list) {} // 使用构造函数进行列表初始化 }; MyStruct myObj = {1, 2, 3, 4}; // 使用列表初始化结构体进行初始化 ``` 在上面的代码,我们定义了一个带有一个参数的构造函数,该参数使用了 `std::initializer_list<int>` 类型,表示可以接受任意数量的 `int` 类型参数。在构造函数的实现,我们将这个参数传递给了成员变量 `myList` 进行初始化。在创建 `myObj` 对象时,我们可以直接使用花括号 `{}` 进行列表初始化,并将列表的值传递给构造函数的参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值