- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
让我们从一些上下文开始。
自定义内存池使用的代码类似于以下内容:
struct FastInitialization {};
template <typename T>
T* create() {
static FastInitialization const F = {};
void* ptr = malloc(sizeof(T));
memset(ptr, 0, sizeof(T));
new (ptr) T(F);
return reinterpret_cast<T*>(ptr);
}
想法是,当使用 FastInitialization
调用时,构造函数可以假设存储已经零初始化,因此只初始化那些需要不同值的成员。
GCC(至少是 6.2 和 6.3)不过有一个“有趣”的优化开始了。
struct Memset {
Memset(FastInitialization) { memset(this, 0, sizeof(Memset)); }
double mDouble;
unsigned mUnsigned;
};
Memset* make_memset() {
return create<Memset>();
}
编译为:
make_memset():
sub rsp, 8
mov edi, 16
call malloc
mov QWORD PTR [rax], 0
mov QWORD PTR [rax+8], 0
add rsp, 8
ret
但是:
struct DerivedMemset: Memset {
DerivedMemset(FastInitialization f): Memset(f) {}
double mOther;
double mYam;
};
DerivedMemset* make_derived_memset() {
return create<DerivedMemset>();
}
编译为:
make_derived_memset():
sub rsp, 8
mov edi, 32
call malloc
mov QWORD PTR [rax], 0
mov QWORD PTR [rax+8], 0
add rsp, 8
ret
也就是说,只有struct
的前16个字节,也就是它的base对应的部分,被初始化了。调试信息确认对 memset(ptr, 0, sizeof(T));
的调用已被完全省略。
另一方面,ICC 和 Clang 都在完整大小上调用了 memset
,这是 Clang 的结果:
make_derived_memset(): # @make_derived_memset()
push rax
mov edi, 32
call malloc
xorps xmm0, xmm0
movups xmmword ptr [rax + 16], xmm0
movups xmmword ptr [rax], xmm0
pop rcx
ret
因此 GCC 和 Clang 的行为不同,问题就变成了:GCC 是正确的并且产生更好的汇编,还是 Clang 是正确的但 GCC 有问题?
或者,就语言律师而言:
在什么情况下构造函数可以依赖存储在其分配存储空间中的先前值?
注意:我认为这只与位置 new
相关,但我很高兴以其他方式显示。
最佳答案
May placement
new
rely on underlying storage value?
不,它可能不会。来自 [dcl.init]:
If no initializer is specified for an object, the object is default-initialized. When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced (5.18).
不确定值意味着不确定。这并不意味着,在放置新表达式的情况下,必须保留以前的内存。允许编译器对内存做任何它想做的事情——包括但不限于什么都不做。
Under which circumstances may a constructor rely on the previous value stored in its allocated storage?
[dcl.init] 中的后续段落列出了在生成不确定值时行为不是未定义的情况,但它们只与无符号窄字符类型有关。
所以,在任何情况下都不能。
关于c++ - 放置 `new` 可以依赖底层存储值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41890635/
我知道它们是匿名类型,但我不明白 Razor 语法。在一些文档中,我找到了这样的示例: @Html.Label("Hello", new { htmlAtributes = new { id = "h
关于:new Object(new Array()) 有一个相当基本的问题,我自己确实无法给出答案,我正在寻求建议: 在js中实例化对象时使用如下方法: var obj = new Object();
在eclipse中右击项目时,“新建文件夹”、“新建源文件夹”和“新建包”有什么区别?他们似乎都在做同样的事情,引用文献并没有说太多。 谢谢 最佳答案 新建文件夹 在项目中创建一个新文件夹。 新建源文
几天来我一直在测试 bolt-cms,我试图了解它是如何工作的。 我想知道新页面、新条目和新展示柜之间有什么区别。 我已阅读 this它并没有填补空白。 最佳答案 Pages、Entries 和 Sh
更新:感谢所有的回答。我发现的最干净的解决方案是这个: if ( k(Arrays.asList(new LinkedList<>())); 我有一个递归方法,可以从列表中生成所有“n 选 k”组合。
我现在想知道这些指令是如何分配内存的。 例如,如果我得到代码怎么办: x = new int[5]; y = new int[5]; 如果分配了这些,它在 RAM 中的实际情况如何?是为每个变量保留整
我希望将其写入output.txt而不清除它 - 只是附加到末尾。但是,当我使用以下两种方法时: public void addEmails(ArrayList emails){ for (i
我正在分配内存,稍后将用于构造具有放置 new 的对象。我应该使用 operator new(n),还是应该使用 new unsigned char[n]?为什么? 最佳答案 因素: new[] 必须
基本上,我的问题是以下代码是否有效。 void* mem = operator new(sizeof(T)); T* instance = new(mem) T; delete instance; 如
很抱歉,如果之前有人问过这个问题,但我想就以下两种用法之间的区别提供一个简明的答案。 VS 似乎将它们都接受为有效代码。 private static void doSomeWork() { /
请告诉我这段代码在做什么,它是否创建多维数组(我认为不是)? 代码片段.. var hanoi_peg = new Array( new Array( 5, 4, 3, 2, 1,
这个问题在这里已经有了答案: String intern() behaviour (4 个答案) When should we use intern method of String on Stri
许多人说您应该避免使用 new Object、new Array(),而是使用 {}。 [] 和真/假。 使用字面量构造来获取对象或数组的新实例而不是使用 new 有什么好处?我知道 Crockfor
我正在开发一个存在内存泄漏的开源库。该库是围绕 boost::asio 构建的数据流服务。服务器端使用堆内存管理系统,该系统提供内存以容纳有限数量的 samples,同时它们等待通过 tcp 连接被推
我从以下函数中得到内存泄漏: int ReadWrite(int socket, char *readfile) { FILE *rf = NULL; rf = fopen(readfile,
在考虑类似的事情时 auto x = new T; 标准是否强制要求内存必须来自operator new——类特定的还是全局的?也就是说,如果缺少特定于类的 operator new,则没有办法从除全
只是出于好奇:为什么 C++ 选择 a = new A 而不是 a = A.new 作为实例化对象的方式?后者不是更像是面向对象的吗? 最佳答案 Just out of curiosity: Why
考虑以下代码: typedef SomeType type_t[2]; SomeType * arr1 = new type_t; //new or new[] ??? type_t * arr2
这个问题在这里已经有了答案: Difference between 'new operator' and 'operator new'? (8 个答案) 关闭 8 年前。 面试题:"new"运算符和
我正在为一个应用程序设计界面,以在 TableLayout 中显示从数据库中提取的一些数据。现在,默认 View 是纵向的,它由一个下拉菜单和一个三列的表格组成。当用户切换到横向时,微调器及其选项可以
我是一名优秀的程序员,十分优秀!