这里有人用过c++的“placement new”吗?如果有,为什么?在我看来,它只在内存映射硬件上有用。
当前回答
脚本引擎可以在本机接口中使用它来从脚本分配本机对象。有关示例,请参阅Angelscript (www.angelcode.com/angelscript)。
其他回答
我也有个主意。 c++确实有零开销原则。 但是异常不遵循这个原则,所以有时它们会被编译器开关关闭。
让我们来看看这个例子:
#include <new>
#include <cstdio>
#include <cstdlib>
int main() {
struct A {
A() {
printf("A()\n");
}
~A() {
printf("~A()\n");
}
char data[1000000000000000000] = {}; // some very big number
};
try {
A *result = new A();
printf("new passed: %p\n", result);
delete result;
} catch (std::bad_alloc) {
printf("new failed\n");
}
}
我们在这里分配一个大的结构体,检查分配是否成功,然后删除它。
但是如果我们关闭了异常,我们就不能使用try block,并且无法处理new[]失败。
我们怎么做呢?以下是如何做到的:
#include <new>
#include <cstdio>
#include <cstdlib>
int main() {
struct A {
A() {
printf("A()\n");
}
~A() {
printf("~A()\n");
}
char data[1000000000000000000] = {}; // some very big number
};
void *buf = malloc(sizeof(A));
if (buf != nullptr) {
A *result = new(buf) A();
printf("new passed: %p\n", result);
result->~A();
free(result);
} else {
printf("new failed\n");
}
}
使用简单的malloc 检查是否是C方式失败 如果成功了,我们就使用新位置 手动调用析构函数(不能直接调用delete) 电话免费,由于我们叫malloc
UPD @Useless写了一个注释,它向我的视图打开了new(nothrow)的存在,在这种情况下应该使用它,但不是我之前写的方法。请不要使用我之前写的代码。对不起。
在http://xll.codeplex.com上查看xll项目中的fp.h文件,它解决了喜欢随身携带维度的数组“与编译器的不必要的亲密关系”问题。
typedef struct _FP
{
unsigned short int rows;
unsigned short int columns;
double array[1]; /* Actually, array[rows][columns] */
} FP;
如果你正在构建一个内核,它很有用——你把从磁盘或页表读取的内核代码放在哪里?你得知道该往哪里跳。
或者在其他非常罕见的情况下,比如当你有大量分配的空间,想要把几个结构放在彼此后面。它们可以这样打包,而不需要使用offset()操作符。不过,还有其他的技巧。
我也相信一些STL实现使用了新位置,比如std::vector。它们以这种方式为2^n个元素分配空间,而不需要总是realloc。
我还有一个想法(它对c++ 11有效)。
让我们看看下面的例子:
#include <cstddef>
#include <cstdio>
int main() {
struct alignas(0x1000) A {
char data[0x1000];
};
printf("max_align_t: %zu\n", alignof(max_align_t));
A a;
printf("a: %p\n", &a);
A *ptr = new A;
printf("ptr: %p\n", ptr);
delete ptr;
}
使用c++ 11标准,GCC给出以下输出:
max_align_t: 16
a: 0x7ffd45e6f000
ptr: 0x1fe3ec0
PTR没有正确对齐。
对于c++ 17标准和更高级的标准,GCC给出了以下输出:
max_align_t: 16
a: 0x7ffc924f6000
ptr: 0x9f6000
PTR对齐正确。
据我所知,c++标准在c++ 17之前不支持过对齐的new,如果你的结构的对齐大于max_align_t,你就会遇到问题。 要在c++ 11中绕过这个问题,可以使用aligned_alloc。
#include <cstddef>
#include <cstdlib>
#include <cstdio>
#include <new>
int main() {
struct alignas(0x1000) A {
char data[0x1000];
};
printf("max_align_t: %zu\n", alignof(max_align_t));
A a;
printf("a: %p\n", &a);
void *buf = aligned_alloc(alignof(A), sizeof(A));
if (buf == nullptr) {
printf("aligned_alloc() failed\n");
exit(1);
}
A *ptr = new(buf) A();
printf("ptr: %p\n", ptr);
ptr->~A();
free(ptr);
}
在这种情况下PTR是对齐的。
max_align_t: 16
a: 0x7ffe56b57000
ptr: 0x2416000
我用它来存储带有内存映射文件的对象。 具体的例子是一个图像数据库,它处理大量的大图像(超过内存容量)。
推荐文章
- decltype(auto)的一些用途是什么?
- Shared_ptr转换为数组:应该使用它吗?
- Printf与std::字符串?
- 禁用复制构造函数
- 只接受特定类型的c++模板
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 为什么ARC仍然需要@autoreleasepool ?
- c++ 11中的递归lambda函数
- 在c++中指针使用NULL或0(零)吗?
- 在c++中,如何将int值附加到字符串中?
- 就性能而言,使用std::memcpy()还是std::copy()更好?
- 为什么布尔值是1字节而不是1位?
- 四舍五入到一个数字的最接近倍数
- 模板默认参数
- c++ auto关键字。为什么它是魔法?