struct Rational
{
int a;
int b;
};
struct NextOnFreeList
{
NextOnFreeList *next;
};
// Build the linked-list
NextOnFreeList* freeList = NULL; // head of the linked-list
size_t size = (sizeof(Rational) > sizeof(NextOnFreeList *)) ? sizeof(Rational) : sizeof(NextOnFreeList *);
NextOnFreeList *runner = static_cast <NextOnFreeList *> new char [size]; // LineA
freeList = runner;
for (int i = 0; i < EXPANSION_SIZE; i++) {
runner->next = static_cast <NextOnFreeList *> new char [size];
runner = runner->next;
}
runner->next = 0;
问题1&gt; LINEA 由于Rational的大小(即8字节)大于NextOnFreeList(即4字节), Linked-list中的每个元素只使用部分已分配的内存。这是对的吗?
// Delete the linked-list
NextOnFreeList *nextPtr = NULL;
for (nextPtr = freeList; nextPtr != NULL; nextPtr = freeList) {
freeList = freeList->next;
delete [] nextPtr; // LineB
}
问题2&gt; LineB 我们为什么要使用'delete [] nextPtr'而不是'delete nextPtr'?
问题3&gt;
Rational* ptr = static_cast<Rational*>( freeList ); // LineC
ptr->a = 10;
ptr->b = 20;
LineC是否属实,我们可以带回原始大小为'size'的所有已分配内存 使用内存来存储Rational中的所有元素。
答案 0 :(得分:2)
Q1:是的,但我宁愿使用std::allocator<Rational>::allocate
(或两者的union
- 你会以这种方式避免对齐问题)
Q2:这实际上很糟糕,因为您应先将其转换为char*
,然后再使用delete[]
。再次,使用std::allocator
会更好。 和:默认实施无关紧要(调用free
),但忘了我说的那样;)...直接使用malloc
/ free
更安全
Q3 ::没关系,但我不确定static_cast
是否会允许reinterpret_cast
或者void*
之间的malloc
可以提供帮助)
编辑:我希望你的 Q3 不是最终的,因为你需要先更新空闲列表(在使用指针之前)。
第二次编辑:链接+注意:隐藏分配器内的空闲列表最适合C ++(直接使用free
/ new[]
或{{ 1}} / delete[]
)
答案 1 :(得分:0)
<强> Q.1:强>
是的,但这不是使用static_cast
的最佳选择。 reinterpret_cast
会更优选。
<强> Q.2:强>
我没有定义的行为来识别您的static_cast
接受简单的delete
。最安全的方法是将此视为数组的原始分配。所以请回到char*
并使用[]delete
Q.3 是的,是的,你可以。
答案 2 :(得分:0)
char*
,因此您必须将其删除(通过转回char*
然后delete[]
)或您有未定义的行为。reinterpret_cast
,则会违反严格的别名规则,再次导致未定义的行为。