Fab*_*ien 8 c++ memory-management c++11
我有一个以这种方式描述的类:
class Foo {
int size;
int data[0];
public:
Foo(int _size, int* _data) : size(_size) {
for (int i = 0 ; i < size ; i++) {
data[i] = adapt(_data[i]);
}
}
// Other, uninteresting methods
}
Run Code Online (Sandbox Code Playgroud)
我无法改变那门课程的设计.
如何创建该类的实例?在调用构造函数之前,我必须保留足够的内存来存储其数据,因此它必须在堆上,而不是在堆栈上.我想我想要的东西
Foo* place = static_cast<Foo*>(malloc(sizeof(int) + sizeof(int) * size));
*place = new Foo(size, data); // I mean : "use the memory allocated in place to do your stuff !"
Run Code Online (Sandbox Code Playgroud)
但我找不到办法让它发挥作用.
编辑:正如评论员所注意到的,这不是一个非常好的整体设计(使用非标准技巧data[0]),唉这是一个我不得不使用的库...
zak*_*ter 11
您可以malloc使用对象的内存,然后使用a placement new在先前分配的内存中创建对象:
void* memory = malloc(sizeof(Foo) + sizeof(int) * size);
Foo* foo = new (memory) Foo(size, data);
Run Code Online (Sandbox Code Playgroud)
请注意,为了销毁此对象,您无法使用delete.您必须手动调用析构函数,然后free在分配的内存上使用malloc:
foo->~Foo();
free(memory); //or free(foo);
Run Code Online (Sandbox Code Playgroud)
另请注意,正如@Nikos C.和@GManNickG建议的那样,您可以使用以下更多C++方式执行相同的操作::operator new:
void* memory = ::operator new(sizeof(Foo) + sizeof(int) * size);
Foo* foo = new (memory) Foo(size, data);
...
foo->~Foo();
::operator delete(memory); //or ::operator delete(foo);
Run Code Online (Sandbox Code Playgroud)
你有一个库来做这件事,但不提供工厂功能?耻辱!
无论如何,虽然zakinster的方法是正确的(虽然我直接调用operator new而不是新建一个chars数组),但它也容易出错,所以你应该把它包起来.
struct raw_delete {
void operator ()(void* ptr) {
::operator delete(ptr);
}
};
template <typename T>
struct destroy_and_delete {
void operator ()(T* ptr) {
if (ptr) {
ptr->~T();
::operator delete(ptr);
}
}
};
template <typename T>
using dd_unique_ptr = std::unique_ptr<T, destroy_and_delete<T>>;
using FooUniquePtr = dd_unique_ptr<Foo>;
FooUniquePtr CreateFoo(int* data, int size) {
std::unique_ptr<void, raw_delete> memory{
::operator new(sizeof(Foo) + size * sizeof(int))
};
Foo* result = new (memory.get()) Foo(size, data);
memory.release();
return FooUniquePtr{result};
}
Run Code Online (Sandbox Code Playgroud)
是的,这里有一些开销,但大部分内容都是可重用的.
| 归档时间: |
|
| 查看次数: |
554 次 |
| 最近记录: |