使用 stl map 作为 struct 的成员

Posted

技术标签:

【中文标题】使用 stl map 作为 struct 的成员【英文标题】:use stl map as member of 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 【参考方案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++ 的工作方式)。所以它与未初始化的数组元素完全有关,仅此而已。 对不起,当你说数组时,我以为你是指地图。我的错误,我不应该假设。

以上是关于使用 stl map 作为 struct 的成员的主要内容,如果未能解决你的问题,请参考以下文章

C++ pair(对组)用法

C++ pair的基本用法总结

cpp►STL容器->排序容器->map

STL源码剖析(set/map)

STL详解—— setmapmultisetmultimap的介绍及使用

STL 的 hash_map 中的碰撞检测