【问题标题】:use stl map as member of struct使用 stl map 作为 struct 的成员
【发布时间】:2013-01-11 01:05:08
【问题描述】:

我正在构建一个结构,其中一个成员是地图。
第一个问题允许这样做吗?编译器没有抱怨。

struct A {  
  map<int, float> B;  
}  

稍后我声明了一个此类数据类型的数组。

A *C = (A *)INTERNAL_CALLOC(..., sizeof(A));  

这里的函数 INTERNAL_CALLOC 是 MALLOC 的函数包装器。
后来在代码中,当我第一次尝试将一个项目插入到数组的第一个元素的映射中时,我得到了一个核心转储。

C[0].B[0] = 0.001;  

知道为什么会这样吗?
谢谢!

【问题讨论】:

  • 代码部分不正确。结构 A 之后的行是“map B;”
  • 你不应该使用 malloc 来分配 C++ 对象(你的结构是)。你应该使用new

标签: c++ stl map


【解决方案1】:

是的,结构中的映射很好。

malloc 分配绝对是好的;构造函数没有被调用。因此,当您尝试使用地图时,它很可能会做一些可怕的事情。

一般经验法则:不要在 C++ 中使用 malloc/calloc/realloc/free。尽可能避免动态分配,并在不可避免时使用new/delete*


* 并阅读智能指针

【讨论】:

  • 我应该怎么做才能确保构造函数被调用?谢谢。
  • 将尝试新建/删除。谢谢
【解决方案2】:

如果您确实必须使用 INTERNAL_CALLOC 进行分配,请使用 Placement new。

首先,你必须为类型A定义一个构造函数和一个析构函数,或者将A定义为一个类:

struct A {
  A(){}
  ~A(){}
  map<int, float> B;  
};

那么你可以简单地调用:

//Allocate an A, uninitialized
A *C = (A *)INTERNAL_CALLOC(..., sizeof(A));  
//Initialize the newly allocated A
new (C) A();

稍后当你释放对象时,你必须显式调用析构函数:

//A *C;
C->~A();
INTERNAL_free(C);

【讨论】:

  • 试过这个方法,但得到了同样的错误。现在我正在切换到使用 new 来分配数组。
【解决方案3】:
A *C = (A *)INTERNAL_CALLOC(..., sizeof(A));  

你在对编译器撒谎。您告诉它来自INTERNAL_CALLOC 的返回值指向A,但它没有,它只是指向零。使用new

【讨论】:

  • 你的话很强大,但我喜欢你的解释:)
【解决方案4】:

用零字节填充内存不会得到有效的std::map&lt;whatever...&gt;

在一定程度上,POD 类型(大约是“纯 C”数据结构)是可能的。

【讨论】:

    【解决方案5】:

    由于您使用std::map 作为会员, 我建议使用std::vector 而不是普通数组作为容器。

    你可以这样做:

    struct A
    {
        std::map<int, int> B;
    };
    
    std::vector<A> vecofmap;    
    
    A elem0;
    A elem1;
    A elem2;
    
    vecofmap.push_back(elem0);
    vecofmap.push_back(elem1);
    vecofmap.push_back(elem2);
    
    vecofmap[0].B[0] = 100;
    
    std::cout << vecofmap[0].B[0] <<std::endl;
    

    那么就不用担心内存分配了。

    【讨论】:

      【解决方案6】:

      使用 malloc 分配内存不会初始化数组元素。

      【讨论】:

      • 它不初始化地图根本,与元素无关。
      • @Ed 数组元素属于 A 类。映射是 A 类的成员,所以如果数组元素没有初始化(就像我说的那样),映射也不会初始化(就像你说过)。如果数组元素已初始化(例如使用 operator new[] 时),则映射也将被初始化(因为这就是 C++ 的工作方式)。所以它与未初始化的数组元素完全有关,仅此而已。
      • 对不起,当你说数组时,我以为你是指地图。我的错误,我不应该假设。
      猜你喜欢
      • 1970-01-01
      • 2019-04-07
      • 2020-07-07
      • 2013-10-03
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      • 1970-01-01
      • 2018-11-13
      相关资源
      最近更新 更多