仅释放分配给 "operator new" 的一部分内存
Freeing only a portion of memory allocated with "operator new"
理论上,如果内存中的 space 是使用 operator new
分配的,是否可以逐步释放该内存?例如,如果使用 void *mem = operator new(sizeof(int)*2)
将内存地址分配给两个 int*
变量,一个在 mem
,另一个在 mem+sizeof(int)
,是否可以释放内存一个,而不是另一个?
我的理解是operator new
只分配内存,并没有调用任何构造函数,所以placement new
用于在内存中精确的space调用构造函数。如果这些分配的内存地址是已知的,但在内存中不一定是线性的(例如存储在内存池 class 的链表中),我想会有一种适当的方法来释放通过遍历内存地址的链表并释放分配大小的内存来分配内存。但是,通过将内存分配给指向适当大小的数据类型的指针,总是会引发运行时错误。
有合适的方法吗?
理论例子:
// This works fine
uintptr_t mem1 = reinterpret_cast<uintptr_t>(operator new(sizeof(int)));
int *a = new(reinterpret_cast<void*>(mem1)) int(1);
printf("a|*a\t\t%p|%d\n", a, *a);
delete a;
// Both of the pointers can be assigned to the appropriate positions...
uintptr_t mem2 = reinterpret_cast<uintptr_t>(operator new(sizeof(int) * 2));
int *b = new(reinterpret_cast<void*>(mem2)) int(2);
printf("b|*b\t\t%p|%d\n", b, *b);
int *c = new(reinterpret_cast<void*>(mem2+sizeof(int))) int(3);
printf("c|*c\t\t%p|%d\n", c, *c);
// ...but attempting to delete them results in a runtime error.
operator delete(b);
operator delete(c);
//using "operator delete(reinterpret_cast<void*>(mem2));" works just fine, but I'm operating on the assumption that the addresses may be non-linear, in a linked-list of addresses of a constant size
18.6.1.1/12 (void operator delete(void* ptr) noexcept
):
Requires: ptr
shall be a null pointer or its value shall be a value returned by an earlier call to the (possibly replaced) operator new(std::size_t
) or operator new(std::size_t,const std::nothrow_t&)
which has not been invalidated by an intervening call to operator delete(void*)
.
我认为在销毁分配的内存方面没有比这更明确的了:标准不允许这样做。
如果您的意思是 "can the new operator allocate a huge chunk of memory and then return part of it to the caller making memory allocation really efficient" 那么一般来说,是的...这已经发生了。对于现代系统,你甚至没有分配任何内存——发生的事情是你被分配了一块虚拟地址space,只有当你写入它时才由真实内存支持,CPU MMU 处理所有这些你.
不支持在应用程序代码级别分配内存并尝试部分释放它,您从 new 中获得的是您必须作为单个块使用的内容。
理论上,如果内存中的 space 是使用 operator new
分配的,是否可以逐步释放该内存?例如,如果使用 void *mem = operator new(sizeof(int)*2)
将内存地址分配给两个 int*
变量,一个在 mem
,另一个在 mem+sizeof(int)
,是否可以释放内存一个,而不是另一个?
我的理解是operator new
只分配内存,并没有调用任何构造函数,所以placement new
用于在内存中精确的space调用构造函数。如果这些分配的内存地址是已知的,但在内存中不一定是线性的(例如存储在内存池 class 的链表中),我想会有一种适当的方法来释放通过遍历内存地址的链表并释放分配大小的内存来分配内存。但是,通过将内存分配给指向适当大小的数据类型的指针,总是会引发运行时错误。
有合适的方法吗?
理论例子:
// This works fine
uintptr_t mem1 = reinterpret_cast<uintptr_t>(operator new(sizeof(int)));
int *a = new(reinterpret_cast<void*>(mem1)) int(1);
printf("a|*a\t\t%p|%d\n", a, *a);
delete a;
// Both of the pointers can be assigned to the appropriate positions...
uintptr_t mem2 = reinterpret_cast<uintptr_t>(operator new(sizeof(int) * 2));
int *b = new(reinterpret_cast<void*>(mem2)) int(2);
printf("b|*b\t\t%p|%d\n", b, *b);
int *c = new(reinterpret_cast<void*>(mem2+sizeof(int))) int(3);
printf("c|*c\t\t%p|%d\n", c, *c);
// ...but attempting to delete them results in a runtime error.
operator delete(b);
operator delete(c);
//using "operator delete(reinterpret_cast<void*>(mem2));" works just fine, but I'm operating on the assumption that the addresses may be non-linear, in a linked-list of addresses of a constant size
18.6.1.1/12 (void operator delete(void* ptr) noexcept
):
Requires:
ptr
shall be a null pointer or its value shall be a value returned by an earlier call to the (possibly replaced)operator new(std::size_t
) oroperator new(std::size_t,const std::nothrow_t&)
which has not been invalidated by an intervening call tooperator delete(void*)
.
我认为在销毁分配的内存方面没有比这更明确的了:标准不允许这样做。
如果您的意思是 "can the new operator allocate a huge chunk of memory and then return part of it to the caller making memory allocation really efficient" 那么一般来说,是的...这已经发生了。对于现代系统,你甚至没有分配任何内存——发生的事情是你被分配了一块虚拟地址space,只有当你写入它时才由真实内存支持,CPU MMU 处理所有这些你.
不支持在应用程序代码级别分配内存并尝试部分释放它,您从 new 中获得的是您必须作为单个块使用的内容。