使用 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 之后的行是“mapmalloc
来分配 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<whatever...>
。
在一定程度上,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 的成员的主要内容,如果未能解决你的问题,请参考以下文章