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> LineA由于Rational的大小(即8个字节)大于NextOnFreeList(即4个字节),链接列表中的每个元素将只使用部分分配的内存。对吗?
// Delete the linked-list
NextOnFreeList *nextPtr = NULL;
for (nextPtr = freeList; nextPtr != NULL; nextPtr = freeList) {
freeList = freeList->next;
delete [] nextPtr; // LineB
}问题2> LineB为什么我们应该使用“delete [] nextPtr”而不是“delete nextPtr”?
问题3>
Rational* ptr = static_cast<Rational*>( freeList ); // LineC
ptr->a = 10;
ptr->b = 20;如果是LineC的话,我们可以将原来分配的所有内存带回来,大小为“size”,并使用内存来存储Rational中的所有元素。
发布于 2014-08-28 15:39:33
Q1:是的,但我宁愿使用std::allocator::allocate (或者两者都使用union )--这样可以避免对齐问题。
Q2:实际上很糟糕,因为您应该先将其转换为char*,然后使用delete[]。同样,使用std::allocator会更好。和:默认实现(调用free)并不重要,但忘记我说过的话;)直接使用malloc/free更安全。
Q3:这很好,但我不确定static_cast是否会允许这样做(reinterpret_cast或中间的void*可能有帮助)
编辑:我希望您的Q3不是最终的,因为您需要首先更新空闲列表(在使用指针之前)。
第二编辑:链接+注意:将空闲列表隐藏在分配程序中对C++最好(直接在其中使用malloc/free,或new[] / delete[])。
发布于 2014-08-28 15:27:17
Q.1:
是的,但这不是最好的使用static_cast的方法。reinterpret_cast会更好。
Q.2:我没有一个定义的行为来识别您的static_cast来接受一个简单的delete。最安全的方法是将其视为数组的原始分配。所以回到char*并使用[]delete
Q.3是的,你可以。
发布于 2014-08-28 15:43:48
char*,因此必须将其删除(通过将其转换回char*,然后转换为delete[]),否则就会有未定义的行为。reinterpret_cast,您将违反严格的混叠规则,再次导致未定义的行为。https://stackoverflow.com/questions/25552243
复制相似问题